use*_*878 11 c++ compiler-construction multithreading
posix标准说像mutex这样的东西会强制执行内存同步.但是,编译器可能会重新排序内存访问.说我们有
lock(mutex);
setdata(0);
ready = 1;
unlock(mutex);
Run Code Online (Sandbox Code Playgroud)
可能会通过编译器重新排序将其更改为下面的代码,对吗?
ready = 1;
lock(mutex);
setdata(0);
unlock(mutex);
Run Code Online (Sandbox Code Playgroud)
那么互斥量如何同步内存访问?更确切地说,编译器如何知道重锁不应该在锁定/解锁时发生?
实际上这里对于单线程方面,就绪分配重新排序是完全安全的,因为就绪不用于函数调用锁(mutex).
编辑:因此,如果函数调用是编译器无法解决的问题,我们可以将其视为编译器内存屏障
asm volatile("" ::: "memory")
Run Code Online (Sandbox Code Playgroud)
一般的答案是,如果你想将它用于POSIX目标,你的编译器应该支持POSIX,而这种支持意味着它应该知道避免重新排序锁定和解锁.
也就是说,这种知识通常是以一种微不足道的方式实现的:编译器不会通过调用可能使用或修改它们的外部函数来重新排序对(不可证实 - 本地)数据的访问.它应该知道一些特别的东西,lock并unlock能够重新排序.
不,它并不是那么简单,因为"对全局函数的调用始终是编译器障碍" - 我们应该添加"除非编译器知道关于该函数的具体内容".它确实发生了:例如pthread_self在Linux(NPTL)上声明了__const__属性,允许gcc重新排序pthread_self()调用,甚至完全消除不必要的调用.
我们可以很容易地想象一个编译器支持获取/释放语义的函数属性,lock而unlock不是完整的编译器障碍.
| 归档时间: |
|
| 查看次数: |
2428 次 |
| 最近记录: |