2 Stimmen

Gemeinsame Nutzung eines Objekts durch mehrere Threads

Wie würden Sie die Objektdaten festlegen, die zwischen Threads gemeinsam genutzt werden und einmal nach dem vollständigen Zyklus von (sagen wir) zwei Threads in der Busy Loop aktualisiert werden müssen?

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

Éditer : Die value kann ein Objekt einer beliebigen Klasse sein.

2voto

Oleg Punkte 219333

Wenn Sie eine thread-sichere Aktualisierung eines Integers implementieren wollen, sollten Sie besser die InterlockedIncrement y InterlockedDecrement o InterlockedExchangeAdd Funktionen. Siehe http://msdn.microsoft.com/en-us/library/ms684122(VS.85).aspx .

Falls Sie doch etwas brauchen EnterCriticalSection y LeaveCriticalSection finden Sie ein Beispiel in http://msdn.microsoft.com/en-us/library/ms686908(v=VS.85).aspx aber ich empfehle Ihnen die Verwendung von EnterCriticalSection im Inneren von __try Block und LeaveCriticalSection innerhalb des __finally Teil dieser Blöcke.

2voto

selbie Punkte 90407

Zwei Vorschläge:

  • Machen Sie das Objekt selbst thread-sicher.
  • Übergabe des Objekts als Instanzdaten an den Thread

Ich werde in meinem Beispiel C++ als Referenz verwenden. Sie können dies leicht auf reines C übertragen, wenn Sie wollen.

// MyObject sind die Kerndaten, die zwischen den Threads ausgetauscht werden sollen.

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

Erstellen Sie dann Ihr Objekt und Ihren Thread wie folgt:

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

}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X