问题标签 [data-race]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
2 回答
1453 浏览

multithreading - 原子对象是否受到保护免受竞争条件的影响?

据我所知,他们不是。

原子对象没有数据竞争,但它们仍然会受到竞争条件的影响:两个线程可能以不可预测的顺序启动,从而使程序结果不确定。

共享数据将是“安全的”(受原子保护),但顺序或时间仍然可能是错误的。

你能证实这一点吗?

0 投票
1 回答
171 浏览

go - go 编译器可以重新排序以下代码吗?

最近,我发现一些代码看起来像这样:

这个程序运行良好,但我认为writem函数体可以通过m = tmpm在 for 循环之前移动来重新排序,因为这不会改变这个 goroutine 中的行为。而这种重新排序将导致concurrent map read and map write问题。正如Go 内存模型所说:

只有当重新排序不会改变语言规范所定义的 goroutine 中的行为时,编译器和处理器才可以重新排序在单个 goroutine 中执行的读取和写入

我是对的,还是这样写代码是安全的?

0 投票
1 回答
248 浏览

language-lawyer - 为什么这个包含两个 volatile 写入数据的 Java 程序没有竞争?

考虑以下 Java 程序:

因为shared被标记volatile,我想说这个程序没有数据竞争。但是,如何基于 JLS(例如,版本 11)来激发这一点?

第 17 章告诉我们:

当一个程序包含两个冲突的访问(第 17.4.1 节)时,这些访问没有按发生前的关系排序,则称为包含数据竞争。

我认为这是 JLS 提供的数据竞争的定义。然后我们有第 17.4.1 节告诉我们:

如果至少有一次访问是写入,则对同一变量的两次访问(读取或写入)称为冲突。

好的,所以我们在这里有冲突的访问,因为我们有两次写入shared. 现在我们必须在两个写入之间建立起之前发生的关系,否则我们就会有比赛。然而,我没有设法找到为什么我们在这里有这种关系。第 17 章告诉我:

如果动作 x 与后续动作 y 同步,那么我们也有 hb(x, y)。

同一章告诉我:

对 volatile 变量 v(第 8.3.1.4 节)的写入与任何线程对 v 的所有后续读取同步(其中“后续”根据同步顺序定义)。

但是在将写入关联到 volatile 变量之前,我还没有发现任何事情发生。这是为什么?

0 投票
1 回答
77 浏览

c - 通过 _Atomic 指针修改非原子结构会产生数据竞争吗?

我试图了解 C11 内存模型是如何工作的,并编写了两个包含表达式的函数conflict(在 的意义上5.1.2.4(p4)):

主要功能:

所以我试图证明程序是否不包含 data-races。以下是我的想法:

  1. 我们知道原子对象上的释放操作与对象上的获取操作同步。所以atomic_store_explicit(&instance, ms, memory_order_release);在 中与中set_first 同步atomic_load_explicit(&instance, memory_order_acquire)print_first

  2. ms -> first = i++由于函数中的副作用set_first出现在atomic_store_explicit(&instance, ms, memory_order_release);程序文本之前,我假设它是在它之前排序的(这是我不确定的,找不到任何规范性参考)。

  3. 结合项目符号1.2.暗示ms -> first = i++ 线程间发生在之前, atomic_load_explicit(&instance, memory_order_acquire);因此它们在关系之前发生

  4. 应用数据竞争定义,我们得出结论,函数和函数uint64_t current = ms -> first;中的冲突操作不会产生数据竞争。print_firstms -> first = i++;set_first

所以行为似乎是明确定义的。

可疑的事情被假定为ms -> first = i++; 之前排序, atomic_store_explicit(&instance, ms, memory_order_release);因为它们在程序文本中一个接一个地发生。

它是正确的还是程序包含数据竞争?

0 投票
1 回答
293 浏览

gcc - 在 clang 或 gcc 中使用线程清理器时是否需要使用 -fopenmp

我正在尝试在给定的代码段(在 ok.c 文件中)上使用threadsanitizer:

这工作正常,没有检测到数据竞争,但是当我尝试给 -fopenmp 选项提供消毒剂时,它会转储终端,并在循环中可能存在数据竞争的位置。

我也尝试使用共享和私有属性来使事情更清楚。

问题:使用线程清理程序时是否需要 -fopenmp 标志?谢谢。

0 投票
2 回答
111 浏览

c++ - 什么保证两个不相关线程中的不同不相关对象没有(不可避免的)竞争条件?

当不同的线程只使用不相关的对象并且字面上不共享任何东西时,它们就不能有竞争条件,对吧?明显地。

实际上所有线程共享一些东西:地址空间。不能保证一个线程使用的内存位置不会在其他时间分配给另一个线程。这对于动态分配对象甚至自动对象的内存来说都是如此:没有规定多个线程的“堆栈”(函数的本地对象)的内存空间是预先分配的(甚至是延迟分配的)、不相交的和表示为通常的线性“堆栈”;它可以是任何具有堆栈(FILO)行为的东西。因此,用于存储自动对象的内存位置可以稍后被另一个线程中的另一个自动对象重用。

这本身似乎是无害且无趣的,因为如何为自动对象腾出空间仅在缺少空间时才重要(非常大的自动数组或深度递归)。

同步呢?不相关的不相交线程显然不能使用任何 C++ 同步原语来确保正确同步,因为根据定义,没有任何东西 (to) 同步 (on),因此在线程之间创建关系之前不会发生任何事情。

如果在线程1中销毁局部变量并退出后,实现重用堆栈的内存范围foo()(包括的位置)来存储线程2中的变量怎么办?ifoo()bar()

在和之前没有发生过i = 1i = 2

这会导致数据竞争和未定义的行为吗?

换句话说,所有多线程程序是否都有可能基于用户无法控制的实现选择产生未定义的行为,这是不可预见的,并且对于他无能为力的种族?

0 投票
5 回答
1358 浏览

c++ - 什么正式保证非原子变量不能看到凭空出现的值并创建像原子松弛理论上可以的数据竞争?

这是关于C++ 标准的形式保证的问题。

该标准指出,std::memory_order_relaxed原子变量的规则允许“凭空出现”/“出乎意料”的值出现。

但是对于非原子变量,这个例子能不能有UB?r1 == r2 == 42在 C++ 抽象机中可能吗?最初这两个变量都没有== 42,因此您希望两个if主体都不应该执行,这意味着不会写入共享变量。

上面的示例改编自标准,该标准明确表示原子对象规范允许这种行为:

[注意:在以下示例中,要求确实允许 r1 == r2 == 42,其中 x 和 y 最初为零:

但是,实现不应该允许这种行为。– 结束注]

所谓的“内存模型”的哪一部分保护非原子对象免受这些由读取看到的无中生有的值引起的交互


当存在具有不同值的竞争条件,如何保证读取共享变量(正常,非原子)看不到这样的值?xy

未执行的主体能否if创造导致数据竞争的自我实现条件?

0 投票
0 回答
72 浏览

c++ - 在同一地图的迭代中更改地图中的值(嵌套迭代器)C ++

我在下面在linux中编译的代码中遇到了一些奇怪的问题,

下面的代码从 Begin 和迭代循环中迭代一个映射“ ObjectsMap ”,我试图更改同一个映射“ ObjectsMap ”中不同键的值。

执行此代码时,我在selfTime中得到不正确/意外的值。但是,如果我在 if() 块中添加一些日志,那么奇怪的是该值是正确的。如果日志被删除,那么我在selfTime中再次得到不正确的值。

这里有什么奇怪的东西。?是因为数据竞争行为吗?

更新1:

我得到的selfTime值不是垃圾。但它是不正确的值,该值高于预期 - 我的意思是一些更不正确的键的“outerItr->second.execTime”也被添加到“innerItr->second.selfTime”

0 投票
0 回答
49 浏览

c++ - 移动构造函数调用的次数比预期的多

我已经逐步完成了这段代码,但不明白为什么移动构造函数被调用 4 次而不是 1 次。不应该只调用一次吗?我已经在 Mac 上使用 CLion 逐步完成了代码。这是控制台上的结果:

这是代码:

0 投票
2 回答
560 浏览

c++ - ThreadSanitizer 检测到数据竞争,问题出在哪里?

在这个示例程序中,我试图避免使用前向声明和循环依赖来利用 lambda 函数(称为 data_race)

但是 ThreadSanitizer 检测到来自 lambda 函数 data_race 的数据竞争。你能帮我理解为什么吗?A 内部的互斥体应该足以避免它。另外,你能帮我找到解决办法吗?


编辑:使用前向声明,不再检测到数据竞争,为什么?(仅发布结构,没有主要内容,对不起,很长的帖子)