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

Tôi đã cố gắng sử dụng phương pháp Interlocked.Add (ref int location1, int value) để thêm vào một số theo cách nguyên tử trong kịch bản đa luồng. Nhưng tôi có một câu hỏi cho bản thân mình: tại sao phương thức trả lại giá trị location1 một lần nữa? Thay vào đó, chúng tôi có thể trực tiếp sử dụng biến được chuyển thành "ref".Tại sao phương thức Interlocked.Add() phải trả về một giá trị?

Một số mã giả dưới đây:

int a = 6; 
int b = 7; 

// some thing else 

Interlocked.Add(ref a, b); 

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

[Nếu bạn đang sử dụng một hoạt động đan cài để tạo ra một giá trị duy nhất, bạn cần phải sử dụng nó trước khi nó biến mất] (http://blogs.msdn.com/b /oldnewthing/archive/2013/04/25/10413997.aspx). – GSerg

+1

Tôi khuyên bạn nên đọc về mô hình bộ nhớ C++ 11 và tại sao nó có tất cả các chi tiết nhỏ mà chúng đưa vào đó. Nó không phải là C# (C# đến trước mô hình bộ nhớ C++ 11), nhưng nó làm một công việc đáng chú ý để chỉ ra cách hoạt động nguyên tử cực kỳ khó hiểu là trừ khi bạn hiểu một số hạn chế phần cứng các hoạt động nguyên tử được thiết kế để làm việc. Nếu bạn không nôn khi bạn đọc về MEMORY_ORDER_CONSUME và kill_dependency, bạn đã sẵn sàng để làm các hoạt động nguyên tử (tôi vẫn nhận được một chút mật ở phía sau cổ họng của tôi, bản thân mình). –

+6

Theo dõi điều gì đó với C# cụ thể như https://msdn.microsoft.com/en-us/magazine/jj863136.aspx. Hai thông tin quan trọng nhất mà tôi có thể cung cấp cho bạn là (1) thời điểm bạn bắt đầu thực hiện lập trình đa luồng bộ nhớ chia sẻ, bạn cần thay đổi thái độ của mình từ "các giá trị của biến ổn định cho đến khi điều gì đó khiến chúng thay đổi" thành "giá trị của các biến thay đổi trừ khi một cái gì đó giữ chúng giống nhau ", và (2) bạn chỉ đơn giản là không hiểu công cụ này cũng đủ để viết các chương trình không có lỗi. Tôi càng tìm hiểu về luồng, tôi càng tự tin rằng tôi đang làm đúng. –

Trả lời

31

Bởi vì biến ref a có thể thay đổi "một lần nữa" trước khi Interlocked lợi nhuận (hoặc ngay cả sau khi nó trả về và trước khi bạn sử dụng a). Hàm này trả về giá trị được tính toán.

Ví dụ:

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 
Các vấn đề liên quan