Tôi đã thử tìm kiếm chi tiết về điều này, tôi thậm chí còn đọc tiêu chuẩn về mutex và atomics ... nhưng tôi vẫn không thể hiểu được khả năng hiển thị của mô hình bộ nhớ C++ 11. Từ những gì tôi hiểu các tính năng rất quan trọng của mutex BESIDE loại trừ lẫn nhau là đảm bảo khả năng hiển thị. Aka nó là không đủ mà chỉ có một chủ đề mỗi lần tăng bộ đếm, điều quan trọng là các chủ đề tăng truy cập đã được lưu trữ bởi các chủ đề được sử dụng cuối cùng mutex (tôi thực sự không biết tại sao mọi người không đề cập đến điều này nhiều hơn khi thảo luận mutexes, có lẽ tôi đã có giáo viên xấu :)). Vì vậy, từ những gì tôi có thể nói doesnt nguyên tử thực thi tầm nhìn trước mắt: (từ người đó duy trì đẩy mạnh :: chủ đề và đã thực hiện c chủ đề ++ 11 và thư viện mutex):Đặt hàng và hiển thị mô hình bộ nhớ?
Một hàng rào với memory_order_seq_cst không thi hành ngay lập tức khả năng hiển thị cho các chủ đề khác (và cũng không phải là hướng dẫn MFENCE). Các ràng buộc đặt hàng bộ nhớ C++ 0x chỉ là --- đặt hàng ràng buộc. memory_order_seq_cst hoạt động tạo thành một đơn đặt hàng tổng, nhưng không có giới hạn về thứ tự đó, ngoại trừ việc nó phải là được tất cả các chủ đề đồng ý và không được vi phạm các ràng buộc khác theo thứ tự . Cụ thể, các chuỗi có thể tiếp tục thấy các giá trị "cũ" trong một thời gian, miễn là chúng thấy giá trị theo thứ tự phù hợp với các ràng buộc.
Và tôi đồng ý với điều đó. Nhưng vấn đề là tôi gặp khó khăn khi hiểu những gì C++ 11 xây dựng liên quan đến nguyên tử là "toàn cầu" và chỉ đảm bảo tính thống nhất trên các biến nguyên tử. Đặc biệt tôi có sự hiểu biết đó (nếu có) của bộ nhớ sau orderings đảm bảo rằng sẽ có một hàng rào bộ nhớ trước và sau khi tải và lưu trữ: http://www.stdthread.co.uk/doc/headers/atomic/memory_order.html
Từ những gì tôi có thể nói std :: memory_order_seq_cst chèn hàng rào mem trong khi khác chỉ thực thi thứ tự của các hoạt động trên vị trí bộ nhớ nhất định.
Vì vậy, ai đó có thể xóa điều này, tôi đoán rất nhiều người sẽ làm lỗi khủng khiếp bằng cách sử dụng lệnh std :: atomic, esp nếu họ không sử dụng mặc định (std :: memory_order_seq_cst memory order)
2. if I ' m đúng không có nghĩa là dòng thứ hai là redundand trong mã này:
atomicVar.store(42);
std::atomic_thread_fence(std::memory_order_seq_cst);
3. làm std :: atomic_thread_fences có yêu cầu tương tự như mutexes theo một nghĩa nào đó để đảm bảo tính nhất quán seq trên nonatomic vars người ta phải làm std :: atomic_thread_fence (std :: memory_order_seq_cst); trước khi tải và tiêu chuẩn :: atomic_thread_fence (std :: memory_order_seq_cst);
sau cửa hàng?
4.
{
regularSum+=atomicVar.load();
regularVar1++;
regularVar2++;
}
//...
{
regularVar1++;
regularVar2++;
atomicVar.store(74656);
}
tương đương với
std::mutex mtx;
{
std::unique_lock<std::mutex> ul(mtx);
sum+=nowRegularVar;
regularVar++;
regularVar2++;
}
//..
{
std::unique_lock<std::mutex> ul(mtx);
regularVar1++;
regularVar2++;
nowRegularVar=(74656);
}
Tôi nghĩ là không, nhưng tôi muốn để đảm bảo.
EDIT: 5. Khẳng định cháy?
Chỉ tồn tại hai chủ đề.
atomic<int*> p=nullptr;
thread đầu tiên viết
{
nonatomic_p=(int*) malloc(16*1024*sizeof(int));
for(int i=0;i<16*1024;++i)
nonatomic_p[i]=42;
p=nonatomic;
}
sợi thứ hai đọc
{
while (p==nullptr)
{
}
assert(p[1234]==42);//1234-random idx in array
}
vì vậy trong 5) cho (int i = 0; i <16 * 1024; ++ i) nonatomic_p [i] = 42; không thể di chuyển sau khi gán p? Bởi vì memory_order_seq Tôi đoán tôi đúng, tôi chỉ muốn kiểm tra. BTW câu trả lời tuyệt vời! – NoSenseEtAl
BTW bạn có thể mở rộng về lý do tại sao 4) là cuộc đua dữ liệu? – NoSenseEtAl
Có, bạn đúng trong 5 --- không thể di chuyển các nhiệm vụ sang 'nonatomic_p [i]' sau khi gán 'p'. –