问题标签 [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.
c++ - 通过引用在 lambda 中捕获本地对象是否会导致数据竞争?
我有一些代码在使用 Thread Sanitizer 运行时导致错误:
在里面RenderWatcher
我有一个构造函数,它在私有字段中设置取消令牌:
还有一些吸气剂:
lambda[&renderWatcher]() { return !renderWatcher.isRenderInProgress(); }
是boost::async
存储在私有字段中的实例,并询问“可以取消此渲染过程吗?”。
TSAN 竞赛在RenderWatcher
构造函数中,在设置 cancelToken 时,并且在没有互斥锁的情况下renderWatcher.isRenderInProgress
读取。cancellationToken
如果 RenderWatcher 是一个局部变量,但它是通过 lambda 中的引用捕获的,我可以进行数据竞争吗?
按价值捕获解决了竞争:
或使用互斥锁进行保护:
这是一场真正的数据竞赛吗?按引用或按值捕获有何不同?
谢谢。
c# - 是否可以在 C# 中使用其自己的变量启动一个线程,这些变量不会被后续调用更新?
我创建了一个类,该类具有由不同线程(在类外)调用的方法。在调用该方法之前,线程通过更新类中的属性字典来更新它们自己的参数集。我通过从字典中选择适当的项目来参数化该方法。
该方法中包含各种变量并执行各种计算。如果计算返回某个值,则该方法将控制权传递给几个外部 API 之一,等待 API 传回一个值,将该值写入数据库,然后退出。
我希望该方法的每个调用都是完全独立的——即线程 A 不应干扰线程 B 中变量的值,反之亦然。我最初的阅读表明这不是用于 C# 中的线程化的模型,而是方法中的每个变量都可以由任何线程访问和更新 - 即 Datarace(?可能在这里使用了不正确的术语)。锁定对我来说并不理想,因为每个线程的执行时间很重要。(如果我锁定,我知道线程将被顺序执行,因为它们引用相同的方法/变量)。
我想我实现了我在 python 中使用线程池的行为,尽管这可能只是我在有限的使用期间很幸运!
如上所述,是否可以在 C# 中让方法调用/线程完全相互独立?如果是这样,请您指出我应该寻找的方向吗?
非常感谢。
更新:根据要求,这是我正在尝试做的代码的摘录。我已经删除了大部分与计算相关的代码,只留下了注释以及不同的类如何调用线程等。
在工作流程方面,我收到一条 websocketssharp 消息(我相信这是一个后台线程)。这可能来自几个 websocket 提要之一,每个提要都包含在自己的命名空间和类中,并且每个提要都以相同的逻辑继续。我评估消息,将其中的价格放入字典中,然后调用一个方法来评估价格以确定我们是否应该交易。然后,此方法进行一些计算并(如果适用)创建交易参数列表,然后调用名为 MarketOrder 的方法,将参数列表传递给它。市价单参数被转换为一个类似的(稍微冗余的)交换方法参数列表,每个参数都有一个设置为 false 的“已完成”参数,这些参数被写入一个类级别(“全局”)列表。然后我们为列表中的每个项目创建一个新线程。每个线程检查全局列表,并从列表中拉出第一个未完成的项目。它将完成的参数设置为 true,然后执行 API 调用。
感谢迄今为止做出回应的人-我正在阅读您的建议...
c++ - std::mutex 使用示例
我已经编写了这段代码作为测试:
该counter
变量是全局变量,因此创建了 2 个线程a
,并且b
我希望找到数据竞争。输出是 200000 而不是随机数。为什么?
此代码是使用 a 的固定版本,mutex
因此全局变量只能访问一次(每次 1 个线程)。结果仍然是 200000 。
事实是这样的。互斥体解决方案给了我 200000 这是正确的,因为一次只有 1 个威胁可以访问计数器。但是为什么非互斥解决方案仍然显示200000?
c++ - C++中多线程的困惑
我试图模拟一个概率问题,其中有n 个客户端和n 个服务器。每个客户端随机向任何服务器发送请求,因此每个服务器可以接收任意数量的请求,我必须计算任何服务器可以接收的预期最大请求数。
我试图通过运行 10,000 次迭代来模拟这一点,在每次迭代中,每个客户端都会选择一个随机服务器并向它发送一个请求,服务器表示为一个大小为 N 的整数数组。
客户端选择一个随机数,然后服务器数组中该索引处的值递增。因为,为了获得更好的结果,问题说N应该是大约 10 6。
所以为了让它更快一点,我使用了多线程,其中每个线程运行 100 次迭代,总共有 10 个线程。
但是多线程代码产生的结果与普通代码截然不同。下面是带有输出的代码片段
普通版
输出
多线程版本
输出
虽然我已经多次运行正常代码,并且每次最大计数 = 9 > 500,并且没有太多的数据分散,我的意思是只有最大值 = 8、9、10、11 具有重要值,其余全部为零.
谁能解释我做错了什么?
提前致谢!
multithreading - 英特尔 Pin 多线程检测:如何仅检测线程之间的共享变量访问?
我正在使用 Intel Pin 动态检测多线程程序以进行一些数据竞争检测。我检测内存读/写指令以在运行时收集内存跟踪,然后分析日志。跟踪收集很简单,它在运行时将内存跟踪(包括时间、线程 id、地址等)存储到缓冲区并在最后将其写入。
我的麻烦是严重的运行时开销(200x - 500x)。根据其他作品,跟踪收集应该只引入不到 100 倍的开销。我试图通过跳过对堆栈的访问来优化它,但这并没有太大帮助。由于我的仪器是在指令粒度上进行的,因此会记录大量访问。因此,我认为减少运行时开销的唯一方法是减少要收集的访问,也就是只记录对线程之间共享变量(与竞争相关的变量)的访问。
我可以通过某种方式找出对 Pin 中共享变量的访问吗?还是有其他方法可以减少运行时开销?
multithreading - 对数据竞争定义的困惑
当程序中有两次内存访问时,就会发生数据竞争,其中:
- 定位到同一个位置
- 由两个线程同时执行
- 不是读取
- 不是同步操作
这个定义取自,它是从一篇研究论文中借用的,所以我们可以假设它是正确的。
现在考虑这个例子:
据我了解,这满足了数据竞赛的定义。我们有两条指令访问相同的位置(标志),它们都不是读取,都是并发的并且不是同步操作。所以输出取决于线程如何交错,可以是“真”或“假”。
如果我们假设这是一场数据竞争,那么我可以在访问之前添加锁并解决这个问题。但是即使我在两个线程中都添加了锁,我们也知道锁中也存在竞争条件。所以任何线程都可以获得锁,并且输出仍然可以是“真”或“假”。
所以这是我的困惑,这是我想问的两个问题:
这是一场数据竞赛吗?如果没有,为什么不呢?
如果这是一场数据竞赛,为什么提议的解决方案不起作用?
go - 是什么导致了这种数据竞争?
为什么这段代码会导致数据竞争?我已经使用了原子添加。
我用这段代码运行命令go run --race
并得到:
你能帮我解释一下吗?以及如何解决此警告?谢谢!
go - golang中复制并发安全吗?
在某些情况下,我会将一些内容复制到切片的不同部分。像这样
它导致DATA RACE
。但它在产品环境中始终表现正确。
所以我的问题是:
- 任何数据竞赛云都是未定义的行为?
- 在这样的练习中,我总能得到正确的结果吗?
go - 使用 cgo 时是否会发生数据竞争?
Goroutines 在 cgo 和 go 的不同堆栈中运行:
C 对 Go 的调用约定或可增长堆栈一无所知,因此对 C 代码的调用必须记录 goroutine 堆栈的所有细节,切换到 C 堆栈,并运行不知道如何调用的 C 代码,或者负责程序的更大的 Go 运行时。
是否有可能触发它们之间共享的变量或类型的数据竞争?
最近,我在初始化切片时遇到错误,例如:
或者
他们俩都随机抱怨“意外故障地址”错误:
更新
controlcan
是一个包装器包,它将定义在Golang 友好的函数.dll
或库中的函数封装起来,例如,向 CAN 设备发送消息或从 CAN 设备接收消息。.so
IMO,在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
:
go - 无法理解 go test -race : RACE: DATA WARNING 堆栈跟踪
我在测试我的项目时遇到了 DATA RACE 警告,我想知道是否有人愿意帮助我破译这个问题。过去我从未尝试过测试 go 例程,并且我发现很难将我的头脑围绕在数据竞赛中。
我在描述中提供了指向未解决问题的链接,并在问题描述中提供了跟踪。
我真的很感激一些帮助,只是从学习调试类似问题和为未来的 go 例程编写更好的测试方面。
https://github.com/nitishm/vegeta-server/issues/52
下面还提供了跟踪的片段