Frage

Die Benennung dieser Funktion scheint, wie dies einige komplizierte Sachen vor sich geht. Wann genau weiß man, dass dies der Weg zu gehen, anstatt so etwas wie dies zu tun:

Vorbereitung     CRITICAL_SECTION cs;     int * p = malloc (sizeof (int)); // Allocation-Site     InitializeCriticalSection (& cs); // HINWEIS für ersten Schreib

Thema # 1      {     * P = 1; // Erste schreiben     }

Thread # 2      {     Entercriticalsection (& cs);     * P = 2; // Zweite schreiben     Leavecriticalsection (& cs);     }

Ich habe einen Schreibvorgang, der in einem Thread erledigt wird:

Run()
{
// some code
m_bIsTerminated = TRUE;
// some more code
}

Dann habe ich eine Lese, die (möglicherweise zur gleichen Zeit) in einem anderen Thread erledigt wird:

Terminate()
{
// some code
if( m_bIsTerminated )
{
m_dwThreadId = 0;
m_hThread = NULL;
m_evExit.SetEvent();
return;
}
// even more code
}

Was ist die beste Lösung, um diese Race-Bedingung zu lösen? Sind kritische Abschnitte der Weg zu gehen oder ist die Verwendung von InterlockedExchangeAdd () nützlicher?

War es hilfreich?

Lösung

InterlockedExchangeAdd wird verwendet, um einen Wert auf eine ganze Zahl als atomare Operation hinzuzufügen, was bedeutet, dass Sie nicht einen kritischen Abschnitt verwenden. Damit entfällt auch das Risiko eines Deadlocks, wenn einer Ihrer Threads eine Ausnahme auslöst -. Sie müssen sicherstellen, dass Sie halten keine Sperre jeder Art, dass andere Threads zu erwerben, dass die Sperre verhindern würde

Für Ihr Szenario können Sie auf jeden Fall eine verriegelte verwenden ...- Funktion, aber ich würde ein Ereignis verwenden (Create, SetEvent, WaitForSingleObject), wahrscheinlich, weil ich finde mich oft, um für mehr als ein Objekt zu warten (Sie warten für null Sekunden in Ihrem Szenario).

Upd: Die Verwendung flüchtiger für die Variable arbeiten kann, aber es wird nicht empfohlen, siehe: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2016.html und http://www-949.ibm. com / software / rational / Café / blogs / GuD-parallel-Multi-Core / tags / c% 2B% 2B0x zum Beispiel.

Wenn Sie tragbar sein wollen, werfen Sie einen Blick auf boost :: thread .

Andere Tipps

In Ihrem Fall gibt es keine Race-Bedingung. Die Variable wird nie auf FALSCH zurückgesetzt, oder? Es ist nur ein Schalter für den Thread „bitte sterben“, nicht wahr? Dann keine Notwendigkeit für die Synchronisation aller Art.

Die InterlockedXXX Familie von Funktionen nutzt Intel CPUs Atom-3-Operanden-Befehle (XADD und CMPXCNG). So sind sie viel billiger als ein kritischer Abschnitt. Und die, die Sie für Thread-sichere Zuordnung wollen, ist InterlockedCompareExchange ().

UPD:. Und die Marke der Variablen als flüchtiges

Stellen Sie sicher, m_bIsTerminated als flüchtig markiert, und Sie sollten in Ordnung sein. Obwohl es mir ziemlich komisch scheint, dass Sie etwas mehr Code nach Einstellung // würden auf true „beendet“. Was genau macht diese Variable angeben?

Ihre „Race Condition“ ist, dass Ihre verschiedenen Elemente // mehr Code in unterschiedlicher Reihenfolge ausgeführt werden können. Ihre Variable ist, dass nicht helfen. Ihr Ziel ist, sie auszuführen in einer deterministischen Reihenfolge zu bekommen? Wenn ja, würden Sie einen Zustandsgröße benötigen in einem Thread und Satz in einer anderen zu warten. Wenn Sie gerade nicht wollen, dass sie gleichzeitig ausgeführt wird, ein kritischer Abschnitt wäre in Ordnung.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top