• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

【Go】原子操作atomic.Value的使用

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

概述
Go的sync/atomic包提供了原子操作,支持的数据类型包括:

int32, int64, uint32, uint64, uintptr, unsafe.Pointer
1
若需要扩大原子操作的适用范围,可以使用atomic包中的Value。利用它可以实现对任意值进行原子得存储与加载。

使用注意点
atomic.Value只有两个指针方法:Store、Load。使用时需要遵循两个原则:1.不能存储nil;2.存储第一个值后,就只能存储这个类型的值。
看一下atom.Value的实现可以发现一个内部的结构ifaceWords,使用unsafe.Pointer存储数据类型及内容得指针

type ifaceWords struct {
typ unsafe.Pointer
data unsafe.Pointer
}
1
2
3
4
在使用Store进行存储时,首先判断待存储值是否为nil,若为nil会直接panic。之后会读取typ,若为nil则会将待存储值得类型、值的指针分别对typ、data进行赋值;若不为nil,则会判断待存储值的类型是否与既有的typ一致,不一致也会引起panic,一致的话则是将新值的指针赋予data。
为了防止在使用是意外出现panic,所以可以考虑在外部先进行合法性校验。

引用类型带来的坑点
因为atom.Value内部实际上维护的是存储值的指针,而这个指针因为不对外暴露,所以认为是并发安全的。然而如果尝试用它来存储引用类型,维护的就是这个引用类型的指针,则不能保证实际的数据是并发安全的。举个例子:
uint32是值类型,切片[]uint32是引用类型,我们使用这样两个函数来尝试修改值。

//值类型
func atomic_value(a uint32) {
var v atomic.Value
v.Store(a)
a = 666
fmt.Println(a)
fmt.Println(v.Load())
}

// 引用类型
func atomic_slice(s []uint32) {
var v atomic.Value
v.Store(s)
s[0] = 666
fmt.Println(s)
fmt.Println(v.Load())
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
然后我们分别调用这两个函数

func TestAtomValue(t *testing.T) {
atomic_value(1)
atomic_slice([]uint32{1,2,3})
}
1
2
3
4
最后它的输出是这样的:

可以看到我们使用Store存入uint32的值a后,我们无论怎么在外部修改a,使用Load都可以获取到我们Store的值。
然而我们若使用Store存入引用类型的切片,我们在外部修改值,Load出来的值也会收到影响。这是因为对于一个引用类型,我们实际上只是Store了一个指针,只是对一个指针的原子操作,而这个指针实际指向的地址的值,并不在atomic.Value的维护下,所以并不是并发安全的。

总结
1.atomic.Value可以实现对自定义类型的原子操作
2.不能存入nil
3.对于同一个atomic.Value不能存入类型不同的值
4.最好不要使用atomic.Value存储引用类型的值,可能导致数据不是并发安全的
————————————————
版权声明:本文为CSDN博主「雨儿酱在鹿上」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/q895431756/article/details/111063656


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
gRPC in ASP.NET Core 3.x -- Protocol Buffer(2)Go语言的例子(下)发布时间:2022-07-10
下一篇:
25_Go基础(闭包_3)发布时间:2022-07-10
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap