问题标签 [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 投票
1 回答
54 浏览

c++11 - C++11 std::threads 未退出

您能否检查以下即使在条件变为 false 后也不会退出的代码?

我试图通过第一个线程打印从 1 到 10 的数字,同样通过第二个线程打印 2 到 20 并且我有 10 个线程,每当计数达到 100 时,我的程序应该通过终止所有线程来安全终止。但这并没有发生,打印后,它卡住了,我不明白为什么?

有数据竞赛吗?请指导。

0 投票
1 回答
88 浏览

go - Go 中的数据竞赛:为什么会发生在 10-11 毫秒以下?

这是我运行的代码:

这是我使用的命令:

这是我注意到的行为:

  • delay设置为 9ms 或更低,始终检测到数据竞争(程序抛出Found 1 data race(s)
  • 设置为 12ms 或更高,永远不会检测到delay数据竞争(程序简单地打印0
  • 设置为 10到delay11ms 时,数据竞争会间歇性发生(即有时会打印0,有时会抛出Found 1 data race(s)

为什么会在 10-11ms 左右发生这种情况?

如果这很重要,我正在使用 Go 1.16.3 darwin/amd64

0 投票
0 回答
82 浏览

swift - MPMediaItem的数组函数很慢

我正在尝试使用applicationQueuePlayerandperform方法编辑我的音乐播放器的队列(详情请点击此处)。但是,每当我应用任何数组函数(mapfilter)时,都需要几秒钟才能完成,这会导致(我认为)数据竞争和崩溃,例如,当用户立即删除两个音轨时。

当我通过一个MPMediaItem数组时,问题就出现了。我认为这不是 MPMediaItem 类的问题,因为我可以map在应用程序的其他地方完成 [MPMediaItem] 的一个,例如从播放列表中获取项目时(与队列项目类似大小的数组) .

该问题仅在MPMediaItemsMPMusicPlayerControllerMutableQueueand中获取时才会发生MPMusicPlayerControllerQueue

这只是 MusicKit API 的错误吗?

0 投票
2 回答
83 浏览

c++ - 在 C++ 中将值从 X 更改为 X 会导致数据竞争吗?

我的代码适用于具有不同布局的大型数据块。布局会决定哪些部分数据是固定的,哪些数据是不固定的。一旦数据被固定在一个块中,它通常就不会再改变了。所以所有代码读取数据总是会看到相同的数据。

但是,其他服务可以在这些块中进行更改,只要它们确定没有代码会读取块的那部分。为了简化代码,包含更改的块将从一个服务发送到另一个服务,而不管块的布局如何。然后接收服务将覆盖整个块,包括未更改的数据。让我用一个例子来说明这一点:

假设我们有以下数据块:

57 23 98 17 25 00 00 00 00 00

并想象前 5 个值是“固定的”。我们服务中的代码只会读取前 5 个值,而不会读取接下来的 5 个值。由于我们的架构设计,我们可以保证这一点。接下来的 5 个值实际上没有意义,所以我在表中填了零来说明这一点。

现在另一个服务确定接下来的 5 个值,将完整的块发送到我们的服务,我们只需用新数据覆盖完整的块。由于前 5 个值是“固定的”,它们保持不变,但传输和覆盖块的代码不知道块的布局,所以它唯一能做的就是覆盖整个块。这是结果:

57 23 98 17 25 08 33 42 71 85

如前所述,前 5 个值没有改变,尽管它们被传输逻辑覆盖。

问题是:这是一场数据竞赛吗?如果其他线程可以同时读取数据,是否允许覆盖具有完全相同值的内存地址?

0 投票
2 回答
103 浏览

loops - 作为 goroutine 对循环变量启动方法调用的意外行为

我阅读了这篇文章并决定自己重复这种行为并进行实验:

游乐场

这是代码输出:

我也不明白,为什么 4 of 5 3 (PrintAddr)are 0xc00000c030,最后一个不一样?


但是,如果我使用指针数组而不是数组,像这样,

游乐场

那么这里一切都很好,每个条目都用相同的地址打印了 2 次:

但是为什么文章中的情况不适用于这里,而我没有得到很多3 (PrintAddr)呢?

0 投票
2 回答
326 浏览

swift - 使用 os_unfair_lock_lock 进行 Swift 访问竞赛

我制作了一个自定义属性包装器,它提供了一种使用os_unfair_lock. 在启用 TSAN 的情况下测试我的包装器后,在获取锁时报告了访问竞争错误os_unfair_lock_lock(如下图所示)

访问种族图像

不知何故,被认为是线程安全的锁定结构被 TSAN 报告为不是这样。这里发生了什么?

0 投票
2 回答
118 浏览

c++ - 如果我在运行时强制冲突表达式之间的“发生在”关系,这是否是一场数据竞赛?

根据cppreference

当一个表达式的计算写入一个内存位置而另一个计算读取或修改相同的内存位置时,这些表达式被称为冲突。具有两个冲突评估的程序存在数据竞争,除非:

a) 两个评估在同一线程或同一信号处理程序中执行,或
b) 两个冲突评估都是原子操作(参见 std::atomic),或
c) 冲突评估之一发生在另一个之前(参见 std::记忆顺序)

我对c点有点困惑。根据 Anthony Williams 的书(C++ concurrency in action),第 5.1.2 节:

如果从不同线程对单个内存位置的两次访问之间没有强制排序,则这些访问中的一个或两个不是原子的,如果一个或两个是写入,那么这是一个数据竞争并导致未定义的行为。根据语言标准,一旦应用程序包含任何未定义的行为,所有赌注都将被取消;整个应用程序的行为现在是未定义的,它可以做任何事情

我了解,如果我强制执行排序,例如使用 std::mutex,这样就不可能同时发生多个(冲突表达式的)评估,那么一切都很好,我的程序将被很好地定义。我喜欢将其视为“编译时命令执行”。

我想了解“运行时命令执行”是否足以消除数据竞争/未定义的行为。

例如,我设计了一个客户端-服务器系统,如下所示:

服务器规格

  • 它将使用 2 个线程(线程 A 和线程 B)。

  • 两个线程将共享一个初始化为 0 的全局 int 变量。

  • 它将在 2 个端口(端口 A 和端口 B)上侦听客户端的消息。

  • 线程 A 将使用端口 A,线程 B 将使用端口 B。

  • 线程 A/B 伪代码:

  • 请注意,在伪代码的第一步和最后一步中进行的网络库/系统调用没有引入线程间同步。

客户规格

  • 它将是单线程的

  • 它将与服务器的上述 2 个端口连接。

  • 它将交替向服务器的两个端口发送消息,从端口 A 开始。

  • 只有在收到上一条消息的确认后,它才会发送下一条消息。

  • 伪代码:

在上面的例子中,服务器的线程 A 和线程 B 共享一个全局变量。有 2 个冲突的表达式(共享变量的增量操作),我没有使用任何语言提供的同步机制。但是,我在运行时强制执行排序。我知道编译器无法知道运行时但在运行时,因为我确保线程 A 和线程 B 永远不能同时访问该变量。

所以我不确定这是否属于数据竞赛的范畴。

所以基本上我的查询是:

  1. 是否有必要在编译时而不是运行时强制排序以避免数据竞争?上述服务器的代码是否属于具有数据竞争的程序类别?

  2. 当线程在不使用 C++ 语言的同步构造(互斥/期货/原子)等的情况下共享数据时,有没有办法在多线程 C++ 程序中在编译时强制排序?

0 投票
2 回答
59 浏览

go - 数据竞争,两个 goroutine 加上相同的 val

考虑下面的代码,在我看来,val 将在 100 到 200 之间,但它总是 200

为什么 val 最后总是 200?

0 投票
0 回答
71 浏览

c++ - C ++中的数据竞争 - 它们可以是良性的吗?

我有一个多线程 c++ 程序,它执行一些密集的持续计算。

我希望程序在计算进行时将进度写入 GUI/控制台。

为此,我让线程设置了一些有关其各自进度的数据,主线程定期检查这些数据以确定已完成的总计算量。

每个线程都被分配了一条单独的数据来写入(即 a 的元素std::vector),因此没有两条数据有多个线程写入它们。

然而,主线程也必须读取这些数据,因此并发性是一个问题。如果两个线程访问相同的数据,并且至少有一个是写入操作,则可能导致未定义行为的数据竞争。

目前我正在使用单个互斥锁来防止这种情况,但我担心这会不必要地减慢我的程序。

这让我想知道 - 并发使用的数据的值对程序逻辑并不重要 - 所以原则上我是否可以删除数据竞争保护(互斥锁) - 允许发生数据竞争 - 并简单地手动检查是否在对它们做任何事情之前,书面值是垃圾吗?还是存在的数据竞争的本质是否会导致更广泛的未定义行为,这可能会破坏我的问题?

还是有另一种更好的方法来做到这一点?在我的脑海中,另一个选择是原子向量,这样至少每个线程都有一个独特的并发保护,这样它们就不会相互影响,可以这么说。

0 投票
0 回答
16 浏览

python - 使用相同数据库的不同进程之间的数据竞争

我有一个系统,其中包括 MySQL 作为数据库和用于组织异步数据处理的 RabbitMQ。有两个进程(在两个不同的容器中)使用相同的记录。第一个更新数据库事务中的记录状态并将消息发送到兔子队列。第二个进程从数据库中获取记录并完成一些工作。问题是第二个进程可以在第一个进程完成记录更新之前从队列中读取消息。

目前,为了避免这个问题,第二个进程检查记录的状态,如果它不对应于目标值,则该进程通过将其重新发送到同一队列来等待更新。

发生此行为是因为发送到队列是在事务上下文中执行的。如果我将发送移到事务外的队列,可能会出现错误或者db事务完成后进程中断,数据库中的状态会改变,但消息不会发送到队列,第二个进程不会处理这条记录。

你有什么建议来解决这个架构问题?