在线程之间共享对象

时间:2010-06-06 08:11:12

标签: winapi multithreading

如何设置线程之间共享的对象数据,并且需要在繁忙循环中(例如)两个线程的完整周期后更新一次?

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_);
 }
}

修改value可以是任何类的对象。

2 个答案:

答案 0 :(得分:2)

如果您希望实现线程安全更新整数,则最好使用InterlockedIncrementInterlockedDecrementInterlockedExchangeAdd函数。请参阅http://msdn.microsoft.com/en-us/library/ms684122(VS.85).aspx

如果您确实需要使用EnterCriticalSectionLeaveCriticalSection,我会在http://msdn.microsoft.com/en-us/library/ms686908(v=VS.85).aspx中找到一个示例,但我建议您在EnterCriticalSection块内使用__tryLeaveCriticalSection这个区块的__finally部分内。{/ p>

答案 1 :(得分:2)

两个建议:

  • 使对象本身线程安全。
  • 将对象作为实例数据传递给线程

我将在我的示例中使用C ++作为参考。如果需要,您可以轻松地将其转换为纯C.

// MyObject是您想要在线程之间共享的核心数据

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;
    }
};

然后,按如下方式创建对象和线程:

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 */         
    }

}
相关问题