两个线程访问共享的int,x。指令重新排序等会产生什么问题。
主题1:
x = 1;
主题2:
obj.f(x);
如果x是声红外波动,会发生什么变化? 如果线程1和线程2在不同的内核上运行会发生什么变化?
答案 0 :(得分:3)
两个线程访问共享int
x
。指令重新排序等会产生什么问题。
没有互斥体?不要这样做,否则你将冒着鼻子的危险。 :-)确切地说,任何事情都可能发生。它甚至可能起作用(只要你不依赖于一致的值)。但真的不这样做。
如果
x
为声明volatile
,会有什么变化?
不多,或者行为会有所不同,但你仍然没有得到你想要的东西。易失性变量用于处理内存映射设备之类的内容,而不是通过CPU缓存。
如果线程1和线程2在不同的内核上运行会发生什么变化?
问题会变得更糟(但你可能也不会立即看到任何差异)。如果没有互斥锁或信号量,您将不会使用任何内存屏障;它们是使事情发挥作用的关键(以及在另一个写入时阻止一个线程读取或写入的正确锁定)并且它们不是标准C ++的全部内容。这就是你使用正确的线程原语的原因;他们为你解决这些尴尬的问题。
请注意,测试不保证能够解决线程一致性问题;它们固有地接近竞争条件,发生的事情通常会根据系统负载而变化。
答案 1 :(得分:2)
volatile
不适用于c ++中的线程同步,而是避免某些编译器优化(参见:http://en.wikipedia.org/wiki/Volatile_variable)
如果需要控制对x的访问,则需要使用互斥锁或原子。
编辑:以下是关于在没有互斥锁的情况下阅读时会发生什么的讨论,即使只有一个整数 - Is it safe to read an integer variable that's being concurrently modified without locking?
答案 2 :(得分:1)
如果不同步线程,x的值可以在线程2的视图中随时更改。
我们来看看:
class A {
public:
A() { x = 0; }
void set() { x = 1; }
int f() { return x + x%2; }
int x;
};
现在,如果线程1调用set
而线程2调用f
,而没有同步,则f的结果是未定义的。它可以是0 + 0%2或1 + 0%2或1 + 1%2。
线程运行的内核数量和数量无关紧要。未使用显式线程同步时,未定义执行顺序。