0

这些问题仅限于 X86/LINUX 环境。

一个线程写一个带锁的变量,其他线程读取这个变量没有锁。当写线程解锁时,其他线程是否可以立即读取新值?

 volatile int a=0;

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

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

一个线程读取一个带锁的变量,另一个线程不带锁地写入这个变量。当read thread read after write完成后,是否可以立即读取新值?

   volatile int a=0;

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

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

3 回答 3

2

一个线程写一个带锁的变量,其他线程读取这个变量没有锁。当写线程解锁时,其他线程是否可以立即读取新值?

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

一个线程读取一个带锁的变量,另一个线程不带锁地写入这个变量。当read thread read after write完成后,是否可以立即读取新值?

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

由于您需要在特定场景中进行操作,因此您需要在此处提供某种形式的同步。最简单的是使用像Semaphore这样的信号计数器。
请注意,volatile它不为您提供序列的排序,它仅确保不会对编译部分进行优化,因此排序仍然是您的责任。

于 2012-04-23T10:27:12.447 回答
2

他们可以,但不能保证。在这两种情况下,您都有未定义的行为。一旦多个线程访问一个对象,并且至少有一个线程修改它,所有访问都必须同步,否则会导致未定义的行为。

根据 C++11 和 Posix,这是正确的。Linux 遵循 Posix 规则。在某些版本的 VC++ 中,volatile已经扩展了原子语义。(在 Posix 下,唯一与 volatile关注信号和longjmp/相关联的语义setjmp。它完全不相关,并且在线程中很大程度上被忽略了。)

于 2012-04-23T10:56:22.910 回答
0

当心。仅仅因为变量包含在锁中,并不意味着如果您的代码的其他部分不保护对a. 在您的第一个示例中,您锁定了对更改的代码的访问,a但随后unlock()您使用了未受保护的读取。就在那次阅读之前或期间,另一个线程可能会改变价值,a给你留下非常意想不到和不可预测的结果。

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

此外,您的使用volatile令人担忧。我不确定你为什么使用它,但我猜它不会给你你所期望的。请阅读内容以获得更完整的解释。

于 2012-04-23T10:41:01.777 回答