- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
假设我们有 2 个线程。一个生产者和一个消费者。我们有生产数据的生产者,以及使用这些数据的消费者。然而守卫不是原子的!
bool isDataReady = false;
int data = 0;
void Producer() {
data = 42;
std::atomic_thread_fence(std::memory_order_release);
isDataReady = true;
}
void Consumer() {
while(!isDataReady);
std::atomic_thread_fence(std::memory_order_acquire);
assert(data == 42);
}
我想知道为什么 isDataReady
上存在数据竞争。通常,正确的代码应该是对原子 bool 变量使用 relaxed
排序。
是不是因为对isDataReady的写(事务)在读之前还没有完成?即使是这样,这真的是个问题吗?
最佳答案
这种数据竞争很危险,您应该注意消除它。它可能不会因为你的运气而表现出来,但它最终会让人头疼。
此代码由于以下几个问题而存在问题:
编译时 Consumer
编译器不知道 isDataReady
可以改变背景,所以发出 while(!isDataReady)
是完全合理的一个无限循环或什么都没有(由于 forward progress guarantee ,正如评论中指出的那样)。
如果写入和/或读取 bool
不是原子的(在大多数平台上不是这种情况,但理论上是可能的)任何读取都可能导致获取垃圾数据。
内存栅栏 std::memory_order_release
确保线程中发生的更改在其他线程使用 std::memory_order_acquire
调用 fence 后可见。 (至少在简化方面)。因此,bool 变量的变化在其他线程中可能是不可见的。
由于现代处理器的超标量架构,操作可能会在运行时由处理器重新排序。所以内存顺序写入 Producer
从 Consumer
可见可能与代码中的不同。
关于c++ - atomic thread fence : Why is there a data race on this non atomic variable? 这有关系吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54110588/
我遇到了 iOS iPad 应用程序崩溃,并从“设备”选项卡中获得了以下崩溃日志: Date/Time: 2017-10-13 15:06:22 -0600 OS Version:
Android 是否支持地理围栏,如果是,那么最早支持地理围栏功能的平台是什么。 最佳答案 在您提出问题时没有支持,但 Google 刚刚发布了该功能作为 Google IO 2013 的一部分: h
我有一个 Worker 类,它运行自己的 thread 来并行执行一些工作。在特定的时间间隔内,我希望它空闲。我有一个界面 class Worker { mutex m_wait; v
最近我遇到了一个波兰信息学奥林匹克竞赛的任务,叫做“Fence”,我无法解决它。 第一行输入包含整数n ( 1 a3 a5 a2 a4 a6等等 来自 n 的范围值,似乎解决方案的复杂性类似
所以我做了一些阅读:https://en.wikipedia.org/wiki/Double-checked_locking和 http://preshing.com/20130930/double-
我正在尝试使用 Vulkan 和 C++ 创建游戏。我已经到了使用多个带线程的命令缓冲区的部分 - 或者我想如果我做得正确。 现在,我遇到了栅栏问题。控制台——我添加了一个验证层——说“Fence 0
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
我可以包含在 asciidoc 代码围栏内吗?这是一个示例: [source,js] ---- function doit() { *var thing;* // local
我正在测试一个应用程序,查看 Xcode > Window > Devices 中的日志,我发现了以下几行: Apr 1 17:09:33 myIphone locationd[2763] : Fe
在他的 talk 即将结束时关于内存屏障(fences),他举了下面的例子(注意:global is not of atomic type): // thread 1
我用 Python 编写了 Rail Fence Cipher。我想知道是否有更好的解决方案。 对于那些不知道rail fence cipher是什么的人来说,它基本上是一种以螺旋方式创建线性模式的方
为了诊断一个棘手的内存损坏错误(内存被随机覆盖),我考虑使用 Electric Fence + 一些自定义 mprotect 调用来确保损坏的数据结构只有在我希望它们被写入时才可写(并且当试图写入它们
我正在使用 Here Javascript API Explorer 来跟踪主要用于地理围栏的移动 map 对象。我想动态传递路线路径和栅栏路径,因为到目前为止它是硬编码在代码中的。 我尝试使用 ja
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
我在 lintcode 上遇到了这个问题,我已经阅读了两个过去的解决方案,但它们对我来说都没有意义。 问题如下: There is a fence with n posts, each post ca
我创建了一个有问题的程序 - buggy.c - 这是缓冲区 t 的缓冲区溢出场景。你可以看到我写了 5 个以上的索引。它工作正常。它永远不会给我一个错误。我在想,为什么会这样?我什至尝试了 Valg
我收到了一份关于我们的 iPad 应用程序崩溃的报告,并附有一条日志消息。日志消息的最后几行如下: Aug 21 08:58:51 2TesterPad backboardd[26] : CoreAn
Rocket CPU中的FENCE指令是做什么的?我尝试通过 fpga 源代码但找不到它。 另外,写缓冲区在哪里实现?我可能会在那里得到答案:) 最佳答案 [Rocket's source code]
以下错误消息是什么意思? fence has already activated -- too late to add writes 以下是如何获取它的示例: 环境 : Mac OS X狮子 mete
我有一个数组中的数字列表,我想计算上栅栏。 我知道我必须计算中位数,这可以使用 math.js 库来完成。 var median = math.median(numList); 第三个四分位数是中位数
我是一名优秀的程序员,十分优秀!