登录
首页 >  Golang >  Go问答

golangatomic.Load 有获取语义吗?

来源:stackoverflow

时间:2024-04-07 22:00:34 353浏览 收藏

Golang小白一枚,正在不断学习积累知识,现将学习到的知识记录一下,也是将我的所得分享给大家!而今天这篇文章《golangatomic.Load 有获取语义吗?》带大家来了解一下##content_title##,希望对大家的知识积累有所帮助,从而弥补自己的不足,助力实战开发!


问题内容

给定一个 c++ 代码片段:

int a = 0;
atomic b{0};

thread 1                         
a = 1;
b.store(1,memory_order_release);

thread 2
while(!b.load(memory_order_acquire)); 
assert(a==1);

我们知道断言永远不会触发。

另一方面,golangatomic.store 使用隐含内存屏障的 xchg 指令,因此它可以导致与 c++11 一样的 memory_order_release 语义。

//go:noescape
func store(ptr *uint32, val uint32)
text runtime∕internal∕atomic·store(sb), nosplit, $0-12
    movq    ptr+0(fp), bx
    movl    val+8(fp), ax
    xchgl   ax, 0(bx)
    ret

但是,atomic.load的实现是纯go代码,这意味着汇编时只是mov指令。

//go:nosplit
//go:noinline
func Load(ptr *uint32) uint32 {
    return *ptr
}

那么,golangatomic.load有获取语义吗?

如果它是如何工作的,如果不是,如何确保内存排序或使 a=1 可见?


解决方案


在 x86/amd64 等强有序架构上,获取加载和释放存储只是常规加载和存储。为了使它们原子化,您需要确保内存与操作数大小对齐(Go 中自动对齐),并且编译器不会以不兼容的方式对它们重新排序,或者优化它们(例如,重用寄存器中的值)从记忆中读取它。)

Go 原子 Load* 和 Store* 函数是顺序一致的。这是一种更强大的内存排序形式,即使在 x86/amd64 上也需要内存栅栏(或具有隐式内存栅栏的指令)。

引用rsc:

今天关于《golangatomic.Load 有获取语义吗?》的内容介绍就到此结束,如果有什么疑问或者建议,可以在golang学习网公众号下多多回复交流;文中若有不正之处,也希望回复留言以告知!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>