2010-03-04 13 views
10

In meinem Versuch, eine threadsichere C++ - Klasse für schwache Zeigervorlagen zu entwickeln, muss ich ein Flag überprüfen, das anzeigt, dass das Objekt noch am Leben ist. Wenn ja, dann setze die Referenzanzahl des Objekts und ich muss beide Schritte atomar ausführen.Wie Vergleichen und Inkrementieren atomar?

Ich kenne die Existenz von intrinsics Funktionen vom Compiler zur Verfügung gestellt, zum Beispiel _InterlockedCompareExchange() und _InterlockedIncrement(). Aber was ich will, ist eine interlockedCompareIncrement() -Funktion, gibt es eine effiziente Möglichkeit, diese intrinsische mit anderen Primitiven zu simulieren, zumindest auf der Windows-x86-Plattform?

+0

Wenn dies auf Windows, sollten Sie so sagen. – Gabe

Antwort

7

Angenommen, value ist Ihre Flag-Variable. Es sollte volatile erklärt werden.

long curvalue; 
long newvalue; 

do 
{ 
    curvalue = value; 
    newvalue = curvalue + 1; 
} 
while(_InterlockedCompareExchange(&value, newvalue, curvalue) != curvalue); 

Wie Sie sehen Sie diese verallgemeinern kann, was auch immer Art von Arithmetik Sie müssen durch die Operationen zu ändern, die berechnen newvalue angewendet werden.

Wenn Sie zwei Werte gleichzeitig vergleichen möchten, empfiehlt es sich, beide Werte in eine einzelne Variable zu packen und dann mit dieser einzelnen Variable zu arbeiten. Da Sie ein Flag in Kombination mit einer Referenzzählung verwenden, würde ich empfehlen, das niedrigste Bit value als "lebendiges" Flag zu verwenden und es dann um jeweils 2 zu erhöhen/verringern. Auf diese Weise können Sie sowohl das Flag als auch die Referenzzählung in eine einzelne 32-Bit-Variable codieren.

+0

Es scheint, wonach ich suche, ich werde tiefer hineinschauen. –

+0

+1: Ich suchte nach einer atomaren IncIfNot-Funktion. Dies ist auch möglich, um mit einer Schleife und _InterlockedCompareExchange() zu schreiben! – mmmmmmmm

1

Wenn Sie Ihre Bibliothek wollen auf mehreren CPU oder multipler Core Maschinen Sie die Hardware-Unterstützung durch die CPU nutzen müssen laufen. Hier sind einige Hinweise für Sie:

http://en.wikipedia.org/wiki/Test-and-set http://software.intel.com/en-us/forums/showthread.php?t=47498

Oder Sie verwenden müssen Mechanismus vom Betriebssystem bereitgestellt sperren. Wie

http://msdn.microsoft.com/en-us/library/ms684841%28VS.85%29.aspx oder http://en.wikipedia.org/wiki/POSIX_Threads