原子<bool>与布尔值受互斥锁保护
atomic<bool> vs bool protected by mutex
假设我们有一个内存区域,某个线程正在向其中写入数据。然后,它将注意力转移到其他地方,并允许任意其他线程读取数据。然而,在某个时间点,它想要重用该内存区域,并将再次写入该内存区域。
写线程提供一个布尔标志(valid
),这表明内存仍然可以有效地读取(即他还没有重用它)。在某些时候,他会将这个标志设置为false,并且再也不会将其设置为true(它只会翻转一次,仅此而已)。
对于顺序一致性,将这两个代码片段分别用于写入器和读取器应该是正确的:
...
valid = false;
<write to shared memory>
...
和
...
<read from shared memory>
if (valid) {
<be happy and work with data read>
} else {
<be sad and do something else>
}
...
我们显然需要做一些事情来确保顺序一致性,即插入必要的获取和释放内存屏障。我们希望在写线程中,在向段写入任何数据之前,将该标志设置为false。我们希望在检查 在内存访问和 和 似乎在这个场景中,使用原子存储和读取隐含的释放和获取操作对我不利。写入器中的RELEASE不而阻止内存访问向上移动到它上面(只是上面的代码不能向下移动)。同样,读取器中的ACQUIRE也不会而不是阻止内存访问向下移动到它上面(只是下面的代码可能不会向上移动)。 如果这是真的,为了使这个场景工作,我需要在写线程中执行ACQUIRE(即加载),在读取线程中执行RELEASE(即存储)。或者,我可以使用普通的布尔标志,用共享互斥锁保护线程中的读写访问(仅对它!)。通过这样做,我将有效地在两个线程中同时拥有ACQUIRE和RELEASE,将 所以这将是 Edit:实际上,原子上的load和store所隐含的的含义似乎是不同的。c++ 11的 相比之下, 因此,如果我的理解是正确的,代码将是正确的标准c++ 11原子,但对于tbb原子,需要添加显式的valid
之前,读取线程从内存中读取数据。后者是因为我们知道是单调的,也就是说,如果在读取后仍然有效,则在读取时它是有效的。valid
访问之间插入一个完整的栅栏将会做到这一点。然而,我想知道,使valid
成为原子是否就足够了?
然后std::atomic<bool> valid = true;
...
valid.store(false); // RELEASE
<write to shared memory>
...
...
<read from shared memory>
if (valid.load()) { // ACQUIRE
<be happy and work with data read>
} else {
<be sad and do something else>
}
...
valid
访问与内存访问分开。atomic<bool>
和mutex
保护的普通bool
之间的一个非常严重的差异,这是正确的吗?std::atomic
使用memory_order_seq_cst
(!),而不是分别使用memory_order_acquire
和memory_order_release
来加载和存储。tbb::atomic
使用memory_semantics::acquire
和memory_semantics::release
而不是memory_semantics::full_fence
。memory_semantics::full_fence
模板参数来加载和存储。
写入器将valid
标志切换为false
并开始写入数据,而读取器可能仍在从中读取数据。
设计缺陷在于错误的假设,即只要读取器在完成读取后检查数据有效性,读写同一内存区域就不是问题。
c++标准称之为数据竞争,它会导致未定义的行为。
正确的解决方案是使用std::shared_mutex
来管理对单个写入器和多个读取器的访问
- 请解释这句话(cout<<1+int((a<b)^((b-a)&1) )<<endl
- 有充分的理由在h文件中使用include保护而不是cpp文件吗
- 呼叫运营商<<临时
- 为什么在保护模式下继承升级不起作用
- 访问被拒绝后,c++中的故障保护代码
- C++:无法访问声明的受保护成员
- 如何防止clang格式在流运算符调用之间添加换行符<<
- 为什么您需要C++头文件的包含保护
- lock_guard是否保护返回值
- <<操作员在下面的行中工作
- 如何在GTK程序运行时禁用屏幕保护程序/电源管理/屏幕消隐
- 继承和友元函数,从基类访问受保护的成员
- 为什么派生类的好友不能使用受保护的成员?
- C++:为什么无法在派生类中访问受保护的构造函数?
- 公共/私有/受保护是否会更改内存中结构的排列?
- 所以我正在为我的学校作业练习继承,但我无法正确实施标题保护
- C2011: 'Card':"类"类型重新定义(尽管使用了包含保护并且没有在文件中重新定义.cpp类)
- 在父类中公开受保护的构造函数
- 如何从其他结构访问受保护的结构变量
- C++标头保护语法和标头放置