【发布时间】:2011-11-19 15:52:56
【问题描述】:
我试着寻找这方面的细节,我什至阅读了关于互斥锁和原子的标准......但我仍然无法理解 C++11 内存模型可见性保证。 据我了解,互斥互斥的非常重要的特性是确保可见性。 Aka每次只有一个线程增加计数器是不够的,重要的是线程增加最后使用互斥锁的线程存储的计数器(我真的不知道为什么人们在讨论时不提这个互斥体,也许我有不好的老师:))。 因此,据我所知, atomic 不会强制立即可见: (来自维护 boost::thread 并实现了 c++11 线程和互斥库的人):
带有 memory_order_seq_cst 的栅栏不强制立即执行 对其他线程的可见性(MFENCE 指令也没有)。 C++0x 内存排序约束就是这样 --- 排序 约束。 memory_order_seq_cst 操作形成一个总顺序,但是 该命令是什么没有限制,除了它必须 所有线程都同意,并且不能违反其他顺序 约束。特别是,线程可能会继续看到“陈旧”的值 有一段时间,只要他们看到的值的顺序与 约束。
我同意。但问题是我很难理解关于原子的 C++11 构造是“全局的”,并且只能确保原子变量的一致性。 特别是,我了解以下哪些(如果有)内存排序保证在加载和存储之前和之后会有一个内存栅栏: http://www.stdthread.co.uk/doc/headers/atomic/memory_order.html
据我所知,std::memory_order_seq_cst 插入了内存屏障,而其他只强制对某些内存位置的操作进行排序。
所以有人可以澄清一下吗,我想很多人会使用 std::atomic 制造可怕的错误,尤其是如果他们不使用默认值(std::memory_order_seq_cst 内存排序)
2. 如果我是对的,这是否意味着此代码中的第二行是多余的:
atomicVar.store(42);
std::atomic_thread_fence(std::memory_order_seq_cst);
3。从某种意义上说,std::atomic_thread_fences 是否与互斥锁具有相同的要求,以确保非原子变量的 seq 一致性必须执行 std::atomic_thread_fence(std::memory_order_seq_cst);
加载前和
std::atomic_thread_fence(std::memory_order_seq_cst);
在商店之后?
4.是
{
regularSum+=atomicVar.load();
regularVar1++;
regularVar2++;
}
//...
{
regularVar1++;
regularVar2++;
atomicVar.store(74656);
}
相当于
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);
}
我认为不是,但我想确定一下。
编辑:
5.
可以断言火吗?
只有两个线程存在。
atomic<int*> p=nullptr;
第一个线程写入
{
nonatomic_p=(int*) malloc(16*1024*sizeof(int));
for(int i=0;i<16*1024;++i)
nonatomic_p[i]=42;
p=nonatomic;
}
第二个线程读取
{
while (p==nullptr)
{
}
assert(p[1234]==42);//1234-random idx in array
}
【问题讨论】:
标签: c++ c++11 mutex atomic memory-barriers