开发者

Sharing an object between threads

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

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜