2015-03-04 14 views
15

Çoklu iş parçacığı senaryosunda atomik bir sayı eklemek için Interlocked.Add (ref int location1, int value) yöntemini kullanmaya çalışıyorum. Ama kendime bir sorum var: yöntem neden konum1 değerini tekrar döndürüyor? Bunun yerine, "ref" olarak iletilen değişkeni doğrudan kullanabiliriz. AşağıdaInterlocked.Add() yöntemi neden bir değer döndürmek zorunda?

Bazı sözde kodu:

int a = 6; 
int b = 7; 

// some thing else 

Interlocked.Add(ref a, b); 

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

[benzersiz bir değer oluşturmak için bir kenetlenmiş operasyonu kullanmak gidiyoruz gitmiş önce, bunu kullanmak gerekir] (http://blogs.msdn.com/b /oldnewthing/archive/2013/04/25/10413997.aspx). – GSerg

+1

C++ 11 bellek modelini okumanızı ve niçin koyduğu tüm küçük detaylara sahip olmanızı öneririm. C# değil (C# C++ 11 bellek modelinden önce geldi), ancak atomik işlemlerin çalışacak şekilde tasarlandığı bazı donanım kısıtlamalarını anlamadıkça inanılmaz derecede dikkat çekici olmayan atomik işlemlerin ne kadar olduğunu gösteren oldukça iyi bir iş. MEMORY_ORDER_CONSUME ve kill_dependency hakkında okurken kusmazsanız, atomik işlemler yapmaya hazırsınız (hala kendimi boğazımın arkasında biraz saflaşıyorum). –

+6

Bunu, https://msdn.microsoft.com/en-us/magazine/jj863136.aspx gibi C# ile ilgili bir şeyle izleyin. Size verebileceğim en önemli iki kavrayış (1), paylaşımlı bellek çoklu iş parçacığı programlaması yapmaya başladığınız an, tutumunuzu "bir şey değişene kadar değişkenlerin değerleri kararlı hale gelene kadar" değiştirmeye ihtiyaç duyduğunuz anda "değişkenlerin değerleri süreklidir" Bir şey onları aynı tutarsa ​​değişmez "ve (2) sadece bu şeyleri hatasız programlar yazacak kadar iyi anlamıyorsunuz. Diş çekme hakkında ne kadar çok şey öğrenirse, o kadar eminim ki onu doğru anlıyorum. –

cevap

31

değişken ref aInterlocked dönmeden önce "Tekrar" değiştirebilir Çünkü (hatta o döndürür ve a kullanmadan önce sonra). Bunun yerine, hesaplanan değeri döndürür.

Örnek:

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 
İlgili konular