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

c++ - 通过引用在 lambda 中捕获本地对象是否会导致数据竞争?

我有一些代码在使用 Thread Sanitizer 运行时导致错误:

在里面RenderWatcher我有一个构造函数,它在私有字段中设置取消令牌:

还有一些吸气剂:

lambda[&renderWatcher]() { return !renderWatcher.isRenderInProgress(); }boost::async存储在私有字段中的实例,并询问“可以取消此渲染过程吗?”。

TSAN 竞赛在RenderWatcher构造函数中,在设置 cancelToken 时,并且在没有互斥锁的情况下renderWatcher.isRenderInProgress读取。cancellationToken

如果 RenderWatcher 是一个局部变量,但它是通过 lambda 中的引用捕获的,我可以进行数据竞争吗?

按价值捕获解决了竞争:

或使用互斥锁进行保护:

这是一场真正的数据竞赛吗?按引用或按值捕获有何不同?

谢谢。

0 投票
1 回答
108 浏览

c# - 是否可以在 C# 中使用其自己的变量启动一个线程,这些变量不会被后续调用更新?

我创建了一个类,该类具有由不同线程(在类外)调用的方法。在调用该方法之前,线程通过更新类中的属性字典来更新它们自己的参数集。我通过从字典中选择适当的项目来参数化该方法。

该方法中包含各种变量并执行各种计算。如果计算返回某个值,则该方法将控制权传递给几个外部 API 之一,等待 API 传回一个值,将该值写入数据库,然后退出。

我希望该方法的每个调用都是完全独立的——即线程 A 不应干扰线程 B 中变量的值,反之亦然。我最初的阅读表明这不是用于 C# 中的线程化的模型,而是方法中的每个变量都可以由任何线程访问和更新 - 即 Datarace(?可能在这里使用了不正确的术语)。锁定对我来说并不理想,因为每个线程的执行时间很重要。(如果我锁定,我知道线程将被顺序执行,因为它们引用相同的方法/变量)。

我实现了我在 python 中使用线程池的行为,尽管这可能只是我在有限的使用期间很幸运!

如上所述,是否可以在 C# 中让方法调用/线程完全相互独立?如果是这样,请您指出我应该寻找的方向吗?

非常感谢。

更新:根据要求,这是我正在尝试做的代码的摘录。我已经删除了大部分与计算相关的代码,只留下了注释以及不同的类如何调用线程等。

在工作流程方面,我收到一条 websocketssharp 消息(我相信这是一个后台线程)。这可能来自几个 websocket 提要之一,每个提要都包含在自己的命名空间和类中,并且每个提要都以相同的逻辑继续。我评估消息,将其中的价格放入字典中,然后调用一个方法来评估价格以确定我们是否应该交易。然后,此方法进行一些计算并(如果适用)创建交易参数列表,然后调用名为 MarketOrder 的方法,将参数列表传递给它。市价单参数被转换为一个类似的(稍微冗余的)交换方法参数列表,每个参数都有一个设置为 false 的“已完成”参数,这些参数被写入一个类级别(“全局”)列表。然后我们为列表中的每个项目创建一个新线程。每个线程检查全局列表,并从列表中拉出第一个未完成的项目。它将完成的参数设置为 true,然后执行 API 调用。

感谢迄今为止做出回应的人-我正在阅读您的建议...

0 投票
3 回答
287 浏览

c++ - std::mutex 使用示例

我已经编写了这段代码作为测试:

counter变量是全局变量,因此创建了 2 个线程a,并且b我希望找到数据竞争。输出是 200000 而不是随机数。为什么?

此代码是使用 a 的固定版本,mutex因此全局变量只能访问一次(每次 1 个线程)。结果仍然是 200000 。

事实是这样的。互斥体解决方案给了我 200000 这是正确的,因为一次只有 1 个威胁可以访问计数器。但是为什么非互斥解决方案仍然显示200000?

0 投票
1 回答
147 浏览

c++ - C++中多线程的困惑

我试图模拟一个概率问题,其中有n 个客户端和n 个服务器。每个客户端随机向任何服务器发送请求,因此每个服务器可以接收任意数量的请求,我必须计算任何服务器可以接收的预期最大请求数。

我试图通过运行 10,000 次迭代来模拟这一点,在每次迭代中,每个客户端都会选择一个随机服务器并向它发送一个请求,服务器表示为一个大小为 N 的整数数组。

客户端选择一个随机数,然后服务器数组中该索引处的值递增。因为,为了获得更好的结果,问题说N应该是大约 10 6

所以为了让它更快一点,我使用了多线程,其中每个线程运行 100 次迭代,总共有 10 个线程。

但是多线程代码产生的结果与普通代码截然不同。下面是带有输出的代码片段

普通版

输出

多线程版本

输出

虽然我已经多次运行正常代码,并且每次最大计数 = 9 > 500,并且没有太多的数据分散,我的意思是只有最大值 = 8、9、10、11 具有重要值,其余全部为零.

谁能解释我做错了什么?

提前致谢!

0 投票
0 回答
710 浏览

multithreading - 英特尔 Pin 多线程检测:如何仅检测线程之间的共享变量访问?

我正在使用 Intel Pin 动态检测多线程程序以进行一些数据竞争检测。我检测内存读/写指令以在运行时收集内存跟踪,然后分析日志。跟踪收集很简单,它在运行时将内存跟踪(包括时间、线程 id、地址等)存储到缓冲区并在最后将其写入。

我的麻烦是严重的运行时开销(200x - 500x)。根据其他作品,跟踪收集应该只引入不到 100 倍的开销。我试图通过跳过对堆栈的访问来优化它,但这并没有太大帮助。由于我的仪器是在指令粒度上进行的,因此会记录大量访问。因此,我认为减少运行时开销的唯一方法是减少要收集的访问,也就是只记录对线程之间共享变量(与竞争相关的变量)的访问。

我可以通过某种方式找出对 Pin 中共享变量的访问吗?还是有其他方法可以减少运行时开销?

0 投票
1 回答
556 浏览

multithreading - 对数据竞争定义的困惑

当程序中有两次内存访问时,就会发生数据竞争,其中:

  • 定位到同一个位置
  • 由两个线程同时执行
  • 不是读取
  • 不是同步操作

这个定义取自它是从一篇研究论文中借用的,所以我们可以假设它是正确的。

现在考虑这个例子:

据我了解,这满足了数据竞赛的定义。我们有两条指令访问相同的位置(标志),它们都不是读取,都是并发的并且不是同步操作。所以输出取决于线程如何交错,可以是“真”或“假”。

如果我们假设这是一场数据竞争,那么我可以在访问之前添加锁并解决这个问题。但是即使我在两个线程中都添加了锁,我们也知道锁中也存在竞争条件。所以任何线程都可以获得锁,并且输出仍然可以是“真”或“假”。

所以这是我的困惑,这是我想问的两个问题:

  1. 这是一场数据竞赛吗?如果没有,为什么不呢?

  2. 如果这是一场数据竞赛,为什么提议的解决方案不起作用?

0 投票
1 回答
349 浏览

go - 是什么导致了这种数据竞争?

为什么这段代码会导致数据竞争?我已经使用了原子添加。

我用这段代码运行命令go run --race并得到:

你能帮我解释一下吗?以及如何解决此警告?谢谢!

0 投票
1 回答
358 浏览

go - golang中复制并发安全吗?

在某些情况下,我会将一些内容复制到切片的不同部分。像这样

它导致DATA RACE。但它在产品环境中始终表现正确。

所以我的问题是:

  1. 任何数据竞赛云都是未定义的行为?
  2. 在这样的练习中,我总能得到正确的结果吗?
0 投票
0 回答
422 浏览

go - 使用 cgo 时是否会发生数据竞争?

Goroutines 在 cgo 和 go 的不同堆栈中运行:

C 对 Go 的调用约定或可增长堆栈一无所知,因此对 C 代码的调用必须记录 goroutine 堆栈的所有细节,切换到 C 堆栈,并运行不知道如何调用的 C 代码,或者负责程序的更大的 Go 运行时。

是否有可能触发它们之间共享的变量或类型的数据竞争?

最近,我在初始化切片时遇到错误,例如:

或者

他们俩都随机抱怨“意外故障地址”错误:

更新

controlcan是一个包装器包,它将定义在Golang 友好的函数.dll或库中的函数封装起来,例如,向 CAN 设备发送消息或从 CAN 设备接收消息。.soIMO,在controlcan包内和其他包中导入切片初始化语句的数据竞争真的很奇怪。

Receive函数中,第一行声明了一个切片cReceive,如上所述,我随机得到了错误。我认为原因unexpected fault address是数据竞争而不是内存损坏,但这里需要的资源只是类型C.struct__VCI_CAN_OBJ,而不是任何变量。我希望我错了。

更糟糕的是,CanObj在其他包中使用的 typeusbcan.go仍然可能触发错误,例如pReceive. 以前,我怀疑原因可能是 的常数2500,因为原始语句是cReceive := make([]C.struct__VCI_CAN_OBJ, FRAME_LENGTH_OF_RECEPTION)。但是当我2500直接将其更改为时,错误仍然发生。

controlcan.go

usbcan.go

更新 2:

我将cReceive创建从 Go 移动到 Cgo,从Kenny Grant窃取,并且 line 的 make-slice 错误cReceive得到解决。

而且我仍然无法弄清楚创建时会发生什么pReceive

0 投票
1 回答
3152 浏览

go - 无法理解 go test -race : RACE: DATA WARNING 堆栈跟踪

我在测试我的项目时遇到了 DATA RACE 警告,我想知道是否有人愿意帮助我破译这个问题。过去我从未尝试过测试 go 例程,并且我发现很难将我的头脑围绕在数据竞赛中。

我在描述中提供了指向未解决问题的链接,并在问题描述中提供了跟踪。

我真的很感激一些帮助,只是从学习调试类似问题和为未来的 go 例程编写更好的测试方面。

https://github.com/nitishm/vegeta-server/issues/52

下面还提供了跟踪的片段