为什么获取和释放内存隔离栅的值不一致? [英] Why does this acquire and release memory fence not give a consistent value?
问题描述
我只是探索使用获取和释放内存围栏的方法,而不理解为什么我有时有时将输出值设为零而不是始终将值设为2的原因
im just exploring the use of acquire and release memory fences and dont understand why i get the value output to zero sometimes and not the value of 2 all the time
我多次运行该程序,并假设释放障碍之前的原子存储和获取障碍之后的原子负载将确保值始终同步
I ran the program a number of times , and assumed the atomic store before the release barrier and the atomic load after the acquire barrier would ensure the values always would synchronise
#include <iostream>
#include <thread>
#include <atomic>
std::atomic<int>x;
void write()
{
x.store(2,std::memory_order_relaxed);
std::atomic_thread_fence(std::memory_order_release);
}
void read()
{
std::atomic_thread_fence(std::memory_order_acquire);
// THIS DOES NOT GIVE THE EXPECTED VALUE OF 2 SOMETIMES
std::cout<<x.load(std::memory_order_relaxed)<<std::endl;
}
int main()
{
std::thread t1(write);
std::thread t2(read);
t1.join();
t2.join();
return 0;
}
原子变量x有时给出的值为0
the atomic varible x gives a value of 0 sometimes
推荐答案
我认为您误解了围栏的目的.栅栏仅在单个执行线程中为编译器和处理器强制执行某种内存操作顺序.您的获取隔离区将不会神奇地使线程等待,直到其他线程执行释放.
I think you are misunderstanding the purpose of fences. Fences only enforce a certain ordering of memory operations for the compiler and processor in a single thread of execution. Your acquire fence will not magically make the thread wait until the óther thread performs the release.
一些文献将描述一个线程中的释放操作与另一个线程中的后续获取操作同步".这样做的关键是,获取动作是后续动作(即,在发布之后订购"获取指令).如果在获取操作之后命令了释放操作,则在写操作和读操作之间没有同步关系.
Some literature will describe that a release operation in one thread "synchronizes with" a subsequent acquire operation in another thread. The key to this is that the acquire action is a subsequent action (i.e. the acquire is ordered "after" the release). If the release action is ordered after your acquire action, then there is no synchronizes-with relation between the write and read operations.
代码之所以不能始终如一地返回您的期望,是因为线程交织有时会在读取之前对写入进行排序,有时会在写入之前进行读取.
The reason why your code doesn't consistently return what you're expecting is because the thread interleavings sometimes order the write before the read, sometimes the read before the write.
如果要保证线程t2
读取线程t1
发布的值2
,则必须强制t2
等待发布发生.教科书示例几乎总是使用保护变量来通知t2
数据已准备好被消耗.
If you want to guarantee that thread t2
reads the value 2
that thread t1
publishes, you're going to have to force t2
to wait for the publish to happen. The textbook example almost invariably uses a guard variable that notifies t2
that the data is ready to be consumed.
I recommend you read a very well-written blog post about release and acquire semantics and the synchronizes-with relation at Preshing on Programming's The Synchronizes-With Relation.
这篇关于为什么获取和释放内存隔离栅的值不一致?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!