2016-04-07 11 views
6

Ich versuche zu lernen und besser zu verstehen Multithreading, aber ich habe auf das Verhalten von atomaren Funktionen wie fetch-and-add hängen. Im speziellen Fall von fetch-and-add ist es ein Verständnis, dass ein Wert (sagen wir mal x, der momentan 5 ist) zu einem Inkrementwert addiert wird (sagen wir 3), die resultierende Summe (8) wird in x geschrieben Ort im Speicher, aber der alte Wert (5) wird zurückgegeben.Warum geben atomare Operationen wie fetch-and-add den alten Wert der Variablen zurück, die geändert wird?

Es gibt mehrere andere solche Funktionen an verschiedenen Stellen (wie OpenGL Atomfunktionen, Java AtomicIntegers, und viele weitere Bereiche), die sich so verhalten. Aber was ich nicht verstehe, ist, warum ein Code-Platz in den Speicher schreiben möchte und dennoch den Wert zurückgibt, den er in erster Linie ändern wollte. Kann mir jemand helfen, das zu beleuchten?

Antwort

2

auf Sergey Antwort ...

ich Fetch-and-add aussehen zu erweitern etwas ähnliches wie ein Semaphor sein; Außer dem fetch-and-add-Aufruf wird alles zu einer atomaren Operation. Hier ist ein Beispiel für einen Algorithmus, der die Verwendung des ursprünglichen Wertes zeigt: http://research.omicsgroup.org/index.php/Ticket_lock

+0

Dies war ein unglaublich hilfreicher Artikel zum Lesen. Danke, Sergey und Dimitar so sehr für die Hilfe und Beispiele! – hashahid

3

Die Antwort ist sehr einfach. Die Art der atomaren Funktionen besteht darin, dass sie den tatsächlichen Wert zum Zeitpunkt der Ausführung ändern (in diesem Fall inkrementieren), der sich von dem Wert unterscheidet, den Ihr Code kannte.

Beispiel:

x = 5; // x is global 
y = atomically_increment(x); 
// what is y? 

nun passiert, wenn x 5 bis 6 rechts geändert werden, bevor Schritt tatsächlich stattfand, y gleich 6 sein würde, und x bis 9.

1

bezüglich Fetch und-add Anweisungen oder Operationen (wie x86's XADD) sparen Sie vor dem Problem, eine CAS-Schleife zu machen und einen erwarteten Anfangswert zu liefern.

Dies bedeutet aber auch, dass Sie nach dem fetch-and-add in Ihrem Code nicht wissen, zu welchem ​​Wert Ihr Inkrement hinzugefügt wurde, und unter schwerem Konflikt den Wert kurz vor dem fetch-and-adding gelesen hat es könnte immer noch weit weg von der Wahrheit sein. Deshalb ist es sehr nützlich, den alten oder neuen Wert als Ergebnis des atomaren Fetch-and-Adds zurückzugeben.

Als Beispiel verwendet Aeron den Wert, der von fetch-and-add zurückgegeben wird, um festzustellen, ob er seinen Puffer rotieren soll (siehe https://youtu.be/eKVpea51tvo?t=31m54s).