- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
假设我们有一个内存区域,某个线程正在向其中写入数据。然后它将注意力转移到别处并允许任意其他线程读取数据。然而,在某个时间点,它想要重用该内存区域并再次写入。
写入器线程提供了一个 bool 标志 ( 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,在将任何数据写入段之前。我们希望在读取器线程之前检查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>
}
...
在这种情况下,使用原子存储和读取的隐含释放和获取操作似乎对我不利。编写器中的 RELEASE 不会阻止内存访问在它上面移动(只是上面的代码可能不会向下移动)。同样,阅读器中的 ACQUIRE 不会阻止内存访问在其上向下移动(只是来自下方的代码可能不会向上移动)。
如果这是真的,为了使这个场景起作用,我还需要在写入线程中进行 ACQUIRE(即加载),并在读取线程中进行 RELEASE(即存储)。或者,我可以只使用一个普通的 bool 标志,并在具有共享互斥锁的线程中保护写入和读取访问(仅对它!)。通过这样做,我将有效地在两个线程中同时拥有一个 ACQUIRE 和一个 RELEASE,将 valid
分开从内存访问访问。
所以这将是 atomic<bool>
之间非常严重的差异和一个普通的bool
受 mutex
保护, 这是正确的吗?
编辑:实际上,加载和存储在原子上隐含的内容似乎有所不同。 std::atomic
C++11 使用 memory_order_seq_cst
对于两者 (!),而不是 memory_order_acquire
和 memory_order_release
分别用于加载和存储。
相比之下,tbb::atomic
使用 memory_semantics::acquire
和 memory_semantics::release
而不是 memory_semantics::full_fence
.
因此,如果我的理解是正确的,那么代码对于标准 C++11 原子是正确的,但是对于 tbb 原子,需要添加显式的 memory_semantics::full_fence
。用于加载和存储的模板参数。
最佳答案
写入器将 valid
标志切换为 false
并开始写入数据,而读取器可能仍在读取数据。
设计缺陷在于错误的假设,即读取和写入同一内存区域不是问题,只要读取器在完成读取后检查数据有效性即可。
C++ 标准称之为数据竞争,它会导致未定义的行为。
正确的解决方案是使用 std::shared_mutex
来管理对单个写入器和多个读取器的访问。
关于c++ - atomic<bool> 与受互斥锁保护的 bool,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38146681/
我每天运行命令将新记录插入 BigQuery 表,并想记录每天插入的记录数。 我创建了一个 QueryJob包含 SELECT 查询和 destination 表的对象。我将 write_dispos
当您登录受密码保护的页面时,WordPress 会设置一个类似于 wp-postpass_hash 的 cookie。 这个 cookie 似乎永远存在。我希望能够为用户提供“注销”链接。如果我不知道
我正在用 C++ 设计一个公共(public) API,我相信我想保留 C++ 属性函数样式约定,它们看起来像 int& Value() 和 const int& Value() const 而不是按
我正在构建一个使用 jQuery 图片库的网站。你可以看一个例子 here . 出于某种原因,当画廊更改图像时,或者当您手动更改图像时,页面高度似乎因为需要更好的词而“闪烁”。新图像似乎增加了页面高度
我正在尝试使用 CSS3 实现一个简单的 3D 照片库。它在 IE10+ 浏览器上运行良好,但在最新版本的 chrome 上有一个小错误,即单击时按钮消失。谁能告诉我如何解决这个问题?提前谢谢你。 w
我想知道为什么其中一些程序会抛出段错误,而另一些则不会。 这个程序抛出一个段错误: #include int main(){ int ar[2096263]; printf("asd
今天我移植了我的旧内存基准测试 从 Borland C++ builder 5.0 到 BDS2006 Turbo C++,发现奇怪的事情。 BCB5 的 exe 运行正常且稳定 来自 BDS2006
下面是我的代码,用于解决 PE 问题 7(“找到第 10001 个素数”): #include using namespace std; bool isPrime(int n, int primes
我有两个 float 元素,右边和左边。 它们的父元素都是 text-align: center, margin: auto: 1. text 999 ' style='curso
我正在为我的 UI 元素制作一个简单的动画。 我有一个动画组件,它有 2 个不同的动画 - ZoomIn 和 ZoomOut。 每当需要在屏幕上显示 UI 元素(例如按钮)时,就会显示这些动画。 我通
我正在使用 .net 3.5 和 vb.net。我对下面提到的每种加密的内部工作知之甚少。我只使用 .net 类库中提供的类。 我有一段信息已经用 TripleDes 加密,然后是 Rijndael,
我有一个关于正确设计 php 文件及其在服务器上的存储的一般性问题。 问题是这样的:我将一个 php 对象的函数拆分到不同的 php 文件中,例如: 文件 1 AndroidFlashCard.php
我在地址表单输入上有自动完成功能。当用户点击建议时,州和邮政编码信息会自动填充。cp_state 是带有状态名称下拉列表的选择框,而cp_zipcode 是邮政编码的输入文本。 我使用下面的 java
我试图按顺序选择记录,但随机限制。 SELECT * FROM tm_winners WHERE paid_out=0 ORDER BY DESC LIMIT RAND(4,8) 但是,我似乎无法随机
我有一张这样的表,我想选取 20 位 HitTest 门的歌手并按字母顺序对他们(这 20 位歌手)进行排序。 id name hit --------------
我正在尝试使用受风影响的雨粒子,也就是 physicsWorld 重力。 我可以看到重力确实对我的 SKSpriteNode 有影响,但我无法对 SKEmitterNode 产生相同的影响。 我只是想
我有一个问题,我在网站加载时调用淡入,但由于 css 过渡效果,元素变为完全不透明,立即淡出然后淡入,我试图找到解决这个问题的方法,因为它看起来很糟糕 jQuery $(window).on("loa
我定义了一个容器元素,包含一个float div和一个ul,并且 ul 元素包含一些 float li 元素。我想清除 ul 的 float ,但 ul 的高度受其 float 兄弟元素的影响。这是
我想使用一项服务。我 100% 确信该服务可以正常工作。 服务电话 public void add(User user) { ConnectionRequest con = new Connectio
如果您在桌面/PC 上访问某人的 instagram 页面,单击搜索栏时,它会向左浮动,然后可以输入文本进行搜索。当搜索字段中没有文本时,搜索图标和“搜索”占位符会回到原来的中心位置。 我假设 jav
我是一名优秀的程序员,十分优秀!