数据争用(data race) 和竞态条件(race condition)

在有关多线程编程的话题中,数据争用(data race) 和竞态条件(race condition)是两个经常被提及的名词,它们两个有着相似的名字,也是我们在并行编程中极力避免出现的。但在处理实际问题时,我们应该能明确区分它们两个。

1.数据争用(data race)

定义:①多个线程对于同一个变量、②同时地、③进行读/写操作的现象并且④至少有一个线程进行写操作。(也就是说,如果所有线程都是只进行读操作,那么将不构成数据争用)
后果:如果发生了数据争用,读取该变量时得到的值将变得不可知,使得该多线程程序的运行结果将完全不可预测,可能直接崩溃。
如何防止:对于有可能被多个线程同时访问的变量使用排他访问控制,具体方法包括使用mutex(互斥量)和monitor(监视器),或者使用atomic变量。

2.竞态条件(race condition)

当编写多线程程序时,常出现的一个错误便是Race Condition, 即竞争危害/竞态条件。当两个或更多线程都能同时获取以及改变共享数据时,竞争危害便发生了。因为各个线程对数据操纵的顺序并不可预知,因此数据改变的结果取决于线程最终的运行顺序。所有的线程都在“Racing”(竞争)以优先获取数据改变数据。

  最常见的竞争危害的情形是一个线程执行条件语句,“检测条件是否满足——执行”,例如:

if (x == 5)    // 检测
{
   y = x * 2;  // 执行
 
   // 如果其他的线程在"if (x == 5)" 和 "y = x * 2" 之间改变了x的值,
   // 那么y最终不会等于10.
}
  所以y最终可能等于10也可能等于其余任意值,完全取决于x是否在检测和执行之间被改变,而此改变的发生与否是未知的。

  为避免竞争危害,通常采取的措施是给共享数据加锁来保证每次只能有一个线程来获取操纵数据。具体如下:

// 为x加锁
if (x == 5)
{
   y = x * 2; // 现在x不再能被改变,直到解锁。
              // 因此y = 10
}
// 解锁x
  当其他线程想要获取x,便需要等待x被解锁。如果x一直未被解锁,那其他线程也将一直等待下去。。。
  有关加锁的更多知识,请搜索mutex, semaphore, critical section, shared resource
--------------------- 

参考:https://blog.csdn.net/he_wolf/article/details/15808441 

           https://blog.csdn.net/gg_18826075157/article/details/72582939 

猜你喜欢

转载自blog.csdn.net/dwj_daiwenjie/article/details/89371679