在哪些情况下我需要锁定变量来同时访问?

sch*_*flo 6 c c++ multithreading

在C或C++程序中,如果2个线程使用相同的全局变量,则需要通过互斥锁来锁定var.

但究竟在哪些情况下呢?

  1. 线程1:读取线程2:读取
  2. 线程1:写线程2:读取
  3. 线程1:写线程2:写

当然你需要锁定案例3,但其他2个案例是什么?案例2(非原子操作)会发生什么?是否存在某种访问冲突或者线程2是否只获得旧值?我对此感到困惑,因为硬件级别的内存和寄存器不能同时访问(在普通的PC硬件中),还是我们有某种并行CPU和并行总线到并行ram芯片?

Sin*_*all 8

想想每个案例中可能发生的事情.让我们只考虑竞争条件:这很简单,这足以让我们看到后果.

在情况1中,变量未被修改,因此无论顺序是什么,两个线程都将读取相同的值.所以基本上没有错.

案例2和案例3更糟糕.假设你有一个竞争条件,并且不知道哪个线程会提前访问.这意味着:

对于情况2:所有操作结束时变量的值都很好(它将是线程1写入的值),但是线程2可能获得变量的旧值,这可能导致崩溃或其他问题.

对于情况3:变量的结束值是不可预测的,因为它取决于最后执行写操作的线程.

对于情况2和3,也可能发生其中一个线程在处于不一致状态时尝试访问该变量,并且您可能最终得到其中一个线程读取的一些垃圾数据(即情况2),在完成所有操作后,甚至在变量中垃圾数据.

所以,锁定案例2和3.

  • 我认为有必要将其添加到答案中,这是非原子操作的主要问题.你的答案似乎意味着原子性.另请注意,锁定不保证任何特定的访问顺序. (4认同)
  • 情况2可能非常糟糕:当线程2读取时,变量可能处于不一致状态. (3认同)
  • 这个答案是不正确的,或者至少是误导性的.案例2是未定义的行为.这不仅仅是获得陈旧价值的问题,任何事情都可能发生. (2认同)