开发者

Sharing an object between threads

开发者 https://www.devze.com 2023-01-02 16:35 出处:网络
How would you set the object data that is shared between threads and needs to be updated once after the complete cycle of (say) two threads in busy loop?开发者_StackOverflow中文版

How would you set the object data that is shared between threads and needs to be updated once after the complete cycle of (say) two threads in busy loop?开发者_StackOverflow中文版

CRITICAL_SECTION critical_section_;

int value; //needs to be updated once after the cycle of any number of threads running in busy loop

void ThreadsFunction(int i)
{

 while (true)
 {
  EnterCriticalSection(&critical_section_);
                /* Lines of Code */
  LeaveCriticalSection(&critical_section_);
 }
}

Edit: The value can be an object of any class.


Two suggestions:

  • Make the object itself thread safe.
  • Pass the object into the thread as instance data

I'll use C++ as a reference in my example. You can easily transpose this to pure C if you want.

// MyObject is the core data you want to share between threads

struct MyObject
{
   int value;
   int othervalue;
   // all all the other members you want here
};


class MyThreadSafeObject
{
private:
    CRITICAL_SECTION _cs;
    MyObject _myojbect;
    bool _fLocked;
public:
    MyThreadSafeObject()
    {
        _fLocked = false
        InitializeCriticalSection();
    }
    ~MYThreadSafeObject()
    {
        DeleteCriticalSection();
    }

    // add "getter and setter" methods for each member in MyObject
    int SetValue(int x)
    {
         EnterCriticalSection(&_cs);
             _myobject.value = x;
         LeaveCriticalSection(&_cs);
    }

    int GetValue()
    {
         int x;
         EnterCriticalSection(&_cs);
             x = _myobject.value;
         LeaveCriticalSection(&_cs);
         return x;
    }

    // add "getter and setter" methods for each member in MyObject
    int SetOtherValue(int x)
    {
         EnterCriticalSection(&_cs);
             _myobject.othervalue = x;
         LeaveCriticalSection(&_cs);
    }

    int GetOtherValue()
    {
         int x;
         EnterCriticalSection(&_cs);
             x = _myobject.othervalue;
         LeaveCriticalSection(&_cs);
         return x;
    }


    // and if you need to access the whole object directly without using a critsec lock on each variable access, add lock/unlock methods
    bool Lock(MyObject** ppObject)
    {
        EnterCriticalSection(&_cs);
        *ppObject = &_myobject;
        _fLocked = true;
        return true;                
    }

    bool UnLock()
    {
        if (_fLocked == false)
            return false;

        _fLocked = false;
        LeaveCriticalSection();
        return true;
    }
};

Then, create your object and thread as follows:

MyThreadSafeObject* pObjectThreadSafe;
MyObject* pObject = NULL;

// now initilaize your object
pObjectThreadSafe->Lock(&pObject);
   pObject->value = 0; // initailze value and all the other members of pObject to what you want them to be.
   pObject->othervalue = 0;
pObjectThreadSafe->Unlock();
pObject = NULL;


// Create your threads, passing the pointer to MyThreadSafeObject as your instance data
DWORD dwThreadID = 0;
HANDLE hThread = CreateThread(NULL, NULL, ThreadRoutine, pObjectThreadSafe, 0, &dwThreadID);


And your thread will operate as follows
DWORD __stdcall ThreadFunction(void* pData)
{
    MyThreadSafeObject* pObjectThreadSafe = (MyThreadSafeObject*)pData;
    MyObject* pObject = NULL;

    while (true)
    {
       /* lines of code */
           pObjectThreadSafe->SetValue(x);
       /* lines of code */         
    }

}


If you want implement thread safe update of an integer you should better use InterlockedIncrement and InterlockedDecrement or InterlockedExchangeAdd functions. See http://msdn.microsoft.com/en-us/library/ms684122(VS.85).aspx.

If you do need use EnterCriticalSection and LeaveCriticalSection you will find an example in http://msdn.microsoft.com/en-us/library/ms686908(v=VS.85).aspx, but I recommend you to use EnterCriticalSection inside of __try block and LeaveCriticalSection inside of the __finally part of this blocks.

0

精彩评论

暂无评论...
验证码 换一张
取 消