multithreading - 在并发编程的上下文中, "data races"和 "race condition"实际上是同一件事吗?

标签 multithreading concurrency language-agnostic data-race

我经常发现这些术语被用在并发编程的上下文中。它们是相同的还是不同的?

最佳答案

不,它们不是同一件事。它们不是彼此的子集。它们也不是彼此的必要条件,也不是充分条件。

数据竞争的定义非常明确,因此,它的发现可以自动化。当来自不同线程的 2 个指令访问同一内存位置时,就会发生数据竞争,这些访问中至少有一个是写入,并且不存在要求这些访问之间任何特定顺序的同步。

竞争条件是语义错误。事件的时间或顺序中出现的缺陷会导致错误的程序行为。许多竞争条件可能是由数据竞争引起的,但这不是必需的。

考虑以下简单示例,其中 x 是共享变量:

Thread 1    Thread 2

 lock(l)     lock(l)
 x=1         x=2
 unlock(l)   unlock(l)

在此示例中,线程 1 和 2 对 x 的写入受锁保护,因此它们始终按照运行时获取锁的顺序强制执行的某种顺序发生。也就是说,写入的原子性不能被破坏;在任何执行中,两次写入之间总是存在先发生的关系。我们只是无法先验地知道哪个写入发生在另一个写入之前。

写入之间没有固定的顺序,因为锁无法提供这一点。如果程序的正确性受到损害,例如当线程 2 写入 x 后又在线程 1 中写入 x 时,我们说存在竞争条件,尽管从技术上讲不存在数据竞争。

检测竞争条件比检测数据竞争有用得多;但这也是很难实现的。

构建反向示例也很简单。 This博文还通过一个简单的银行交易示例很好地解释了其中的差异。

关于multithreading - 在并发编程的上下文中, "data races"和 "race condition"实际上是同一件事吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11276259/

相关文章:

android - Amazon S3 TransferUtility 在应用程序关闭时停止,即使在 WorkManager 中也是如此

multithreading - 如何从我自己的线程安全地修改 JavaFX GUI 节点?

c - 如何测量线程通过条件变量所花费的时间?

java - 为什么 Semaphore 可以工作,而 ReentrantLock 却不能?

Java volatile 语义,JMM 保证

language-agnostic - 所谓的 "no-overhead"系统语言的运行时环境是什么?

python - 使用threading模块在python中实现线程

c# - Entity Framework 线程安全

security - 通过使用更长的密文获得额外的安全性

c# - 开发游戏 - 如何执行需要多个游戏循环的事情?