POSIX标准规定像互斥锁这样的东西会强制进行内存同步。然而,编译器可能会重新排序内存访问。假设我们有
lock(mutex);
setdata(0);
ready = 1;
unlock(mutex);
编译器重新排序后,它可能会被改变为以下代码,对吗?
ready = 1;
lock(mutex);
setdata(0);
unlock(mutex);
那么互斥锁如何同步内存访问呢?更准确地说,编译器如何知道在锁定/解锁之间不应该进行重排?
实际上,在单线程方面,就就绪赋值重排而言是完全安全的,因为就绪在函数调用lock(mutex)中没有使用。
编辑后:如果函数调用是编译器无法跨越的内容,那么我们可以将其视为类似于编译器内存屏障的东西吗?
asm volatile("" ::: "memory")
lock()
和unlock()
只是编译器的函数调用,我怀疑这样的重新排序会发生。 - Andreas Fester