gpt4 book ai didi

c++ - C++ 中良性竞争条件的保证

转载 作者:太空狗 更新时间:2023-10-29 21:21:18 25 4
gpt4 key购买 nike

我知道 C++ 标准不保证存在数据竞争(我相信数据竞争具有未定义的行为,这意味着任何事情都会发生,包括程序终止、修改随机内存等...)。

是否存在任何架构,其中由一个线程写入内存位置和一个线程从同一位置读取(没有同步)的数据竞争不会导致读取操作读取未定义的值并且内存位置是“最终”(在内存屏障之后)更新为写入操作写入的值?

[编辑以将“竞争条件”替换为“数据竞争”]

最佳答案

数据竞争的问题不是,您可以在机器级别读取错误的值。 数据竞争的问题在于,编译器和处理器都对代码进行了大量优化。为了确保这些优化在存在多个线程的情况下是正确的,他们需要有关可以在线程之间共享的变量的额外信息。例如,此类优化可以:

  • 重新排序操作
  • 添加额外的加载和存储操作
  • 删除加载和存储操作

Hans Boehm 有一篇很好的良性数据竞赛论文,名为 How to miscompile programs with "benign" data races .以下摘自这篇论文:

Double checks for lazy initialization

This is well-known to be incorrect at the source-code level. A typical use case looks something like

if (!init_flag) {
lock();
if (!init_flag) {
my_data = ...;
init_flag = true;
}
unlock();
}
tmp = my_data;

Nothing prevents an optimizing compiler from either reordering the setting of my_data with that of init_flag, or even from advancing the load of my_data to before the first test of init_flag, reloading it in the conditional if init_flag was not set. Some non-x86 hardware can perform similar reorderings even if the compiler performs no transformation. Either of these can result in the final read of my_data seeing an uninitialized value and producing incorrect results.


这是另一个示例,其中 int x 是共享变量,int r 是局部变量。

int r = x;
if (r == 0)
printf("foo\n");
if (r != 0)
printf("bar\n");

如果我们只想说,读取 x 会导致未定义的值,那么程序将打印“foo”或“bar”。但是如果编译器按如下方式转换代码,程序也可能同时打印两个字符串或一个都不打印。

if (x == 0)
printf("foo\n");
if (x != 0)
printf("bar\n");

关于c++ - C++ 中良性竞争条件的保证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22746683/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com