2016-11-30 55 views
0

考虑下面的代码:代码被编译器跨互斥边界重新排序

int a = 0, b = 0; 
boost::mutex m; 
a++; 
m.lock(); 
m.unlock(); 
b++; 

做什么锁是他们告诉编译器“好吧,忘记了片刻的C++标准,我不在乎什么优化如果你严格遵循这个规则,它将被允许。你不能重新排序跨越这个边界的任何内存访问“。这是否意味着a++;将始终在b++;之前发生?或者这是否意味着,如果在锁之间有声明,请不要使用a++b++重新排序?

+5

鉴于编译器可以看到'a'和'b'是局部变量,它可以像往常一样优化它们。在给定的代码中,另一个线程无法看到有问题的“int”,所以互斥体不会影响它们。 –

回答

0

这个问题已经很好地回答了Baum mit Augen的评论。

但是,如果“A”和“B”是全球变量,取决于编译器互斥锁征收的内存屏障可保证读宣布挥发性,/写表达式将不会在重新排序边界。

这意味着读取“b”并且发现它的线程已经增加,并且在此之后执行类似的互斥锁以施加内存屏障,并且最后读取“a”,保证发现“a”具有也被修改了。

MSVC有这种行为,还有一些其他编译器。