多线程环境中的变量同步

时间:2012-04-23 10:24:00

标签: c++ c multithreading

问题仅限于X86 / LINUX环境。

一个线程用锁写一个var,其他线程读取这个var而没有锁。   当写入线程解锁时,其他线程可以立即读取新值吗?

 volatile int a=0;

   /* thread 1(write) */    
   lock();  
   a = 10;  
   unlock();  

   /* thread 2(read) */  
   printf("%d",a);

一个线程使用锁读取var,另一个线程写入此var而不使用锁。    写完成后读取线程读取时,是否可以立即读取新值?

   volatile int a=0;

   /* thread 1(read) */  
   lock();  
   printf("%d",a);  
   unlock();  

   /* thread 2(write) */  
   a = 10;  

3 个答案:

答案 0 :(得分:2)

  

一个线程用锁写一个var,其他线程读取这个var而没有锁。当写入线程解锁时,其他线程可以立即读取新值吗?

是的,他们可以,但是确保所有读取线程在写入开始之前都不会读取的内容?

  

一个线程使用锁读取var,另一个线程写入此var而不使用锁。写完成后读取线程读取时,是否可以立即读取新值?

是的,但又是什么确保了读写的顺序?

由于您需要在某种情况下进行操作,因此您需要在此处提供某种形式的同步。最简单的方法是使用信号计数器,如信号量 请注意,volatile没有为您提供序列的排序,它只能确保对compilres部分没有优化,因此排序仍然是您的责任。

答案 1 :(得分:2)

他们可以,但不能保证。在这两种情况下,你都有 未定义的行为。只要有多个线程访问对象, 并且至少有一个线程修改它,所有访问必须是 同步或未定义的行为结果。

根据C ++ 11和Posix,这是真的。 Linux遵循Posix 规则。在某些版本的VC ++中,volatile已经扩展了 原子语义学。 (在Posix下,唯一与之相关的语义 volatile关注信号并longjmp / setjmp。这完全是 在线程中无关紧要且被忽略。)

答案 2 :(得分:0)

小心点。仅仅因为变量被包含在一个锁中,并不意味着如果代码的其他部分不保护对{{{}的访问,那么即使在锁中,其他线程也无法读取它 1}}。在第一个示例中,您锁定了对a更改的代码的访问权限,但在a之后您使用了不受保护的读取。在读取之前或期间,另一个线程可能会更改unlock()的值,从而使您产生非常意外和不可预测的结果。

换句话说,您不是锁定对变量本身的访问,而是将代码中的某些路径限制为互斥

此外,您对a的使用也很令人担忧。我不确定你为什么使用它,但我猜它不会给你你所期待的。请阅读this以获得更全面的解释。