2011-10-26 39 views
18

Trên đoạn mã sau:std :: nguyên tử <int> sụt lần và so sánh

std::atomic<int> myint; //Shared variable 
//(...) 
if(--myint == 0) { 
    //Code block B 
} 

Có thể rằng nhiều hơn một truy cập chủ đề khối Tôi tên là "Mã Block B"?

Vui lòng xem xét tràn rằng sẽ không xảy ra, rằng 'nếu' đang được thực hiện đồng thời bởi nhiều hơn một chủ đề, rằng việc sửa đổi chỉ để Myint trong toàn bộ chương trình là --myint bên trong nếu và rằng myint được khởi tạo với giá trị dương.

+0

Tại sao bạn cho rằng điều đó không thể thực hiện được? Nếu đó là thao tác duy nhất bạn thực hiện trên 'myint' thì cuối cùng nó sẽ tràn. – Patrick

+1

@Patrick sẽ là hành vi không xác định. –

+2

Câu hỏi thực sự là nếu std :: atomic :: operator-- trả về nguyên tử giá trị cũ. – cdleonard

Trả lời

16

C++ 0x giấy N2427 (Atomics) khẳng định gần như sau. Tôi đã thay đổi từ ngữ hơi quá của nó dễ dàng hơn để đọc cho tình hình sụt cụ thể, các bộ phận tôi đã thay đổi trong đậm:

Effects: nguyên tử thay thế các giá trị trong đối tượng với kết quả của cắt giảm áp dụng cho giá trị trong đối tượng và toán hạng đã cho. Bộ nhớ bị ảnh hưởng theo đơn đặt hàng. Các hoạt động này là các hoạt động đọc-sửa-ghi theo nghĩa của định nghĩa "đồng bộ hóa với" trong [phần mới được thêm bởi N2334 hoặc người kế thừa], và do đó cả hai thao tác và đánh giá đã tạo ra giá trị đầu vào đồng bộ hóa với bất kỳ đánh giá nào đọc giá trị cập nhật.

Returns: nguyên tử, giá trị của đối tượng ngay trước sụt lần.

Hoạt động nguyên tử đảm bảo rằng toán tử giảm sẽ trả về giá trị mà biến được giữ ngay trước thao tác, đây là nguyên tử để không có giá trị trung gian từ các bản cập nhật của một chuỗi khác.

Điều này có nghĩa sau đây là chỉ hành có thể có của mã này với 2 chủ đề:

(Initial Value: 1) 
Thread 1: Decrement 
Thread 1: Compare, value is 0, enter region of interest 
Thread 2: Decrement 
Thread 2: Compare, value is -1, don't enter region 

hoặc

(Initial Value: 1) 
Thread 1: Decrement 
Thread 2: Decrement 
Thread 1: Compare, value is 0, enter region of interest 
Thread 2: Compare, value is -1, don't enter region 

Trường hợp 1 là thật nhàm chán mong đợi như vậy.

Trường hợp 2 xen kẽ các hoạt động giảm và thực hiện các phép so sánh sau này. Vì thao tác giảm và tìm nạp là nguyên tử, không thể cho chuỗi 1 nhận giá trị khác 0 để so sánh. Nó không thể nhận được -1 vì hoạt động là nguyên tử ... việc đọc diễn ra tại thời điểm giảm và không phải là tại thời điểm so sánh. Thêm chủ đề sẽ không thay đổi hành vi này.

+3

Lưu ý rằng tôi đã kiểm tra N3291, và mặc dù nó sử dụng từ ngữ khác nhau, nó đồng ý với điều này. –

+0

Điều này vẫn đúng cho "--myint; if (myint == 0) {}"? – paulm

+2

@paulm Hoàn toàn không đúng nếu bạn giảm và kiểm tra trong hai câu lệnh khác nhau. Phải được thực hiện trong cùng một tuyên bố. – SoapBox

-1

Không, không thể có nhiều hơn một chuỗi đi vào khối, do các ràng buộc của bạn. Nhưng không phải là nó đảm bảo rằng bất kỳ chủ đề bao giờ đi vào khối này:

thread A: decrement myint to 0 

thread B: decrement myint to -1 

thread A: compare to 0 -> false -> don't enter (and neither anyone else) 

Nếu đây là một vấn đề (mà tôi giả định), sau đó mã này sẽ không hoạt động (ít nhất là không luôn).

+1

vì vậy nếu tôi có: thread A: decrement to 1, thread B: decrement to 0, thread A : so sánh với 0 đúng, chuỗi B: so sánh với 0 đúng. –

+0

@ AndréPuel Ah, tôi nghĩ bạn đã cho tôi (và câu trả lời của bạn). –

+0

@ AndréPuel Điều đó là không thể, toán tử - thực hiện giảm và tìm nạp trong một lệnh duy nhất, vì vậy ngay cả trong thứ tự thực hiện mà bạn đã chỉ định trong bình luận của bạn giá trị trong luồng A sẽ là 1. – SoapBox

1

Không rõ ràng rằng khối mã sẽ luôn thực thi. Nếu toán tử "-" được thực thi theo cách nó lưu trữ giá trị cũ trong giá trị trả về và giá trị của nó trong một lệnh nguyên tử duy nhất (tôi chắc chắn x86 có hướng dẫn như vậy), thì có, nó sẽ hoạt động như một khối loại trừ lẫn nhau cho nhiều luồng. Tôi không chắc chắn làm thế nào nó hoạt động bằng cách mặc định, nhưng câu trả lời nằm lẽ trong tài liệu tiêu chuẩn mới:

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2427.html

Các vấn đề liên quan