Sự thất bại của đồng bộ hóa kiểu Dekker thường được giải thích với sắp xếp lại các hướng dẫn. Ví dụ: nếu chúng tôi viếtTại sao không phải là một hàng rào C++ 11 gain_release đủ để đồng bộ hóa Dekker?
atomic_int X;
atomic_int Y;
int r1, r2;
static void t1() {
X.store(1, std::memory_order_relaxed)
r1 = Y.load(std::memory_order_relaxed);
}
static void t2() {
Y.store(1, std::memory_order_relaxed)
r2 = X.load(std::memory_order_relaxed);
}
Sau đó, tải có thể được sắp xếp lại với các cửa hàng, dẫn đến r1==r2==0
.
Tôi đã chờ đợi một hàng rào acquire_release để ngăn chặn loại sắp xếp lại:
static void t1() {
X.store(1, std::memory_order_relaxed);
atomic_thread_fence(std::memory_order_acq_rel);
r1 = Y.load(std::memory_order_relaxed);
}
static void t2() {
Y.store(1, std::memory_order_relaxed);
atomic_thread_fence(std::memory_order_acq_rel);
r2 = X.load(std::memory_order_relaxed);
}
Tải trọng không thể di chuyển trên hàng rào và các cửa hàng không thể di chuyển bên dưới hàng rào, và do đó kết quả xấu cần được ngăn chặn .
Tuy nhiên, các thử nghiệm hiển thị r1==r2==0
vẫn có thể xảy ra. Có một giải thích dựa trên sắp xếp lại cho điều này? Lỗ hổng trong lý luận của tôi đâu?