Let's say I have 1 counter starting at value 2, some non-atomic boolean variable and 4 threads.

//Initialization (happens before any thread execute).
std::atomic<int> count = ATOMIC_VAR_INIT(2);
bool someBoolean = false;

Thread 1:

count.fetch_sub(1, std::memory_order_release);

Thread 2:

someBoolean = true;
count.fetch_sub(1, std::memory_order_release);

Thread 3:

while(count.load(std::memory_order_acquire) != 0);
//Now, we're out of the while loop...
assert(someBoolean);

Thread 4:

while(std::atomic_thread_fence(std::memory_order_acquire), 
      count.load(std::memory_order_relaxed) != 0);
//Now, we're out of the while loop...
assert(someBoolean);

Is it possible that the assertions at Thread 3 or Thread 4 may fire?

有帮助吗?

解决方案

Thread 4 may fire the assertion because you use the load operation and the memory fence in incorrect order. You have to load the count variable first, then place the memory acquire fence.
In general case you have to place a Release fence before writing to a synchronization flag and place an Acquire fence after reading it.

You can find the detailed explanation and examples of Acquire/Release memory fences in this post from the great Jeff Preshing's blog: http://preshing.com/20130922/acquire-and-release-fences/

Thread 3 (and Thread 4 after fixing the function call order) will not fire an assertion because synchronize-with relationship between threads is established correctly.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top