Совместное использование объекта между потоками - PullRequest
2 голосов
/ 06 июня 2010

Как бы вы установили данные объекта, которые совместно используются потоками и должны обновляться один раз после полного цикла (скажем) двух потоков в занятом цикле?

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 ]

2 голосов
/ 07 июня 2010

Два предложения:

  • Сделать сам объект потокобезопасным.
  • передать объект в поток как данные экземпляра

Я буду использовать 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 */         
    }

}
2 голосов
/ 06 июня 2010

Если вы хотите реализовать поточнобезопасное обновление целого числа, вам лучше использовать функции InterlockedIncrement и InterlockedDecrement или InterlockedExchangeAdd. Смотри http://msdn.microsoft.com/en-us/library/ms684122(VS.85).aspx.

Если вам нужно использовать EnterCriticalSection и LeaveCriticalSection, вы найдете пример в http://msdn.microsoft.com/en-us/library/ms686908(v=VS.85).aspx,, но я рекомендую вам использовать EnterCriticalSection внутри блока __try и LeaveCriticalSection внутри __finally часть этого блока.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...