如果我锁定std::mutex
,我会不会有记忆围栏?我不确定它是暗示还是强迫你获得围栏。
更新
在RMF的评论后发现此参考文献。
答案 0 :(得分:14)
据我所知,这内容包含在:
1.10多线程执行和数据竞赛
第5段:
该库定义了许多原子操作(第29条)和对互斥锁的操作(第30条) 特别标识为同步操作。这些操作在使一个线程中的分配对另一个线程可见时起特殊作用。在一个或多个存储器位置上的同步操作是消费操作,获取操作,释放操作,或获取和释放操作两者。没有相关内存位置的同步操作是围栅,可以是获取围栏,释放围栏,也可以是获取和释放围栏。此外,还有轻松的原子操作,它们不是同步操作,还有原子读 - 修改 - 写操作,它们具有特殊的特性。 [注意:例如,获取互斥锁的呼叫将对包含互斥锁的位置执行获取操作。相应地,释放相同互斥锁的调用将在这些相同位置执行释放操作。非正式地,对A执行释放操作会强制其他内存位置上的其他内存位置变得可见,以便稍后对A执行消耗或获取操作的其他线程可见。“轻松”原子操作不是同步操作,即使像同步操作一样,他们不能参与数据竞赛。 - 后注]
答案 1 :(得分:12)
解锁互斥锁与锁定互斥锁同步。我不知道编译器对实现有什么选择,但是你得到了相同的栅栏效果。
答案 2 :(得分:-1)
仅当互斥锁由不同线程共享时,锁定和解锁互斥锁才有用。如果编译器知道不是这种情况,就好像互斥锁是一个不占用地址(也不引用其地址)的自动变量一样,则无需为锁定/解锁操作生成有意义的代码。
锁定/解锁互斥操作不能替代通过调用atomic_thread_fence
执行的“匿名”(未链接到任何特定的共享同步对象)获取/释放操作;但可能似乎总是与当前的天真的编译器支持线程一起使用,从而有效地提供了atomic_thread_fence
等效项。但是,当编译器开始优化无用的锁定操作时,它们将破坏这种不合格的代码。
C / C ++线程语义(*)不允许替代一般正确的atomic_thread_fence
:任何删除对atomic_thread_fence
的调用的代码转换仅在上下文中正确。>
(*)“ C / C ++线程语义” 不是“ C / C ++编程语言线程语义”:C和C ++基于相同的同步原语规范,这并不意味着有C / C ++语言)