2015-03-04 8 views
15
public static int Add(ref int location1,int value) 

Ich habe versucht, die Methode Interlocked.Add (ref int location1, int value) zu verwenden, um eine Zahl atomar im Multithreading-Szenario hinzuzufügen. Aber ich habe eine Frage an mich selbst: Warum gibt die Methode den Wert von location1 zurück? Stattdessen könnten wir direkt die Variable verwenden, die als "ref" übergeben wird.Warum muss die Interlocked.Add() Methode einen Wert zurückgeben?

Einige Pseudo-Code unten:

int a = 6; 
int b = 7; 

// some thing else 

Interlocked.Add(ref a, b); 

// Use the variable 'a' here. 
+3

[Wenn Sie eine Verriegelungsfunktion verwenden werden einen eindeutigen Wert zu generieren, müssen Sie es benutzen, bevor es weg ist] (http://blogs.msdn.com/b /oldnewthing/archive/2013/04/25/10413997.aspx). – GSerg

+1

Ich würde empfehlen, über das C++ 11-Speichermodell zu lesen, und warum es all die kleinen Details enthält, die sie hineinlegen. Es ist nicht C# (C# kam vor dem C++ 11 Speichermodell), aber es hat eine bemerkenswert gute Arbeit nur zu zeigen, wie unglaublich unintuitive atomare Operationen sind, wenn Sie mit einigen der Hardwarebeschränkungen atomare Operationen sind so konzipiert, arbeiten verstehen. Wenn Sie nicht kotzen, wenn Sie über MEMORY_ORDER_CONSUME und kill_dependency lesen, sind Sie bereit, atomare Operationen zu tun (ich immer noch ein wenig Galle in der Rückseite meiner Kehle, ich). –

+6

dass folgen mit etwas C# spezifisch wie https://msdn.microsoft.com/en-us/magazine/jj863136.aspx auf. Die wichtigsten zwei Einsichten, die ich Ihnen geben kann, sind (1) sobald Sie Multi-Thread-Programmierung mit gemeinsamem Speicher beginnen, müssen Sie Ihre Einstellung ändern von "Werte von Variablen sind stabil, bis etwas sie verändert" in "Werte von Variablen sind konstant Änderungen, es sei denn, etwas hält sie gleich ", und (2) Sie verstehen dieses Zeug einfach nicht gut genug, um fehlerfreie Programme zu schreiben. Je mehr ich über Threading lerne, desto weniger zuversichtlich bin ich, dass ich es richtig verstehe. –

Antwort

31

Da die Variable ref a "wieder" vor Interlocked kehrt ändern könnte (oder auch nachdem er zurückkehrt und bevor Sie verwenden a). Die Funktion gibt stattdessen den berechneten Wert zurück.

Beispiel:

int a = 5; 

// on thread 1 
int b = Interlocked.Add(ref a, 5); // b = 10 

// on thread 2, at the same time 
int c = Interlocked.Add(ref a, 5); // c = 15 

// on thread 1 
Thread.Sleep(1000); // so we are "sure" thread 2 executed 
Thread.MemoryBarrier(); // just to be sure we are really reading a 
bool x1 = (b == 10); // true 
bool x2 = (a == 15); // true 
Verwandte Themen