gpt4 book ai didi

c++ - 编译器内存屏障和互斥量

转载 作者:可可西里 更新时间:2023-11-01 15:14:55 32 4
gpt4 key购买 nike

posix 标准说互斥量之类的东西会强制执行内存同步。但是,编译器可能会重新排序内存访问。假设我们有

lock(mutex);
setdata(0);
ready = 1;
unlock(mutex);

它可能会被编译器重新排序更改为下面的代码,对吧?

ready = 1;
lock(mutex);
setdata(0);
unlock(mutex);

那么互斥体如何同步内存访问呢?更准确地说,编译器如何知道重新排序不应该发生在锁定/解锁之间?

实际上对于单线程方面来说,就绪赋值重新排序是完全安全的,因为函数调用锁(互斥锁)中没有使用就绪。

编辑:因此,如果函数调用是编译器无法理解的,我们可以将其视为像

这样的编译器内存屏障吗?
asm volatile("" ::: "memory")

最佳答案

一般的回答是,如果你想将它用于 POSIX 目标,你的编译器应该支持 POSIX,并且这种支持意味着它应该知道避免跨锁定和解锁重新排序。

也就是说,这种知识通常以一种微不足道的方式获得:编译器不会通过调用可能使用或修改它们的外部函数来重新排序对(不可证明的本地)数据的访问。它应该知道关于lockunlock 的一些特殊 以便能够重新排序。

不,它不是像“对全局函数的调用始终是编译器障碍”那么简单——我们应该添加“除非编译器知道关于该函数的某些特定内容”。它确实发生了:例如Linux (NPTL) 上的 pthread_self 使用 __const__ 属性声明,允许 gccpthread_self() 调用中重新排序,甚至完全消除不必要的调用。

我们可以很容易地想象一个支持获取/释放语义的函数属性的编译器,使lockunlock小于完整 编译器障碍。

关于c++ - 编译器内存屏障和互斥量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14437895/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com