sync/atomic 库使用小结
sync/atomic 库提供了原子操作的支持,原子操作直接有底层CPU硬件支持,因而一般要比基于操作系统API的锁方式效率高些。本文对 sync/atomic 中的基本操作进行一个简单的介绍。
原子增值
用于对变量值进行原子增操作,并返回增加后的值。
e.g.var sum uint32 = 100var wg sync.WaitGroupfor i := 0; i < 50; i++ {wg.Add(1)go func() {defer wg.Done()//sum += 1 //1atomic.AddUint32(&sum, 1) //2}()}wg.Wait()fmt.Println(sum)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
通过对比//1与//2的结果,可以很清楚的看到原子操作起到的作用。使用//1时,可以看到sum的值是不定的,取决于sum的同步访问情况;使用//2时,结果是确定而且正确的,同一时间只有一个goroutine修改sum。
函数原型:
atomic.AddUint32(addr *uint32, delta uint32) uint32atomic.AddUint64(addr *uint64, delta uint64) uint64atomic.AddInt32(addr *int32, delta int32) int32atomic.AddInt64(addr *int64, delta int64) int64atomic.AddUintptr(addr *uintptr, delta uintptr) uintptr
- 1
- 2
- 3
- 4
- 5
CAS
先比较变量的值是否等于给定旧值,等于旧值的情况下才赋予新值,最后返回新值是否设置成功。
e.g.var sum uint32 = 100var wg sync.WaitGroupfor i := uint32(0); i < 100; i++ {wg.Add(1)go func(t uint32) {defer wg.Done()atomic.CompareAndSwapUint32(&sum, 100, sum+1)}(i)}wg.Wait()fmt.Println(sum)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
可以看到sum的值只改变了一次,只有当sum值为100的时候,CAS才将sum的值修改为了sum+1。
函数原型:
atomic.CompareAndSwapUint32(addr *uint32, old, new uint32) bool
atomic.CompareAndSwapUint64(addr *uint64, old, new uint64) bool
atomic.CompareAndSwapInt32(addr *int32, old, new int32) bool
atomic.CompareAndSwapInt64(addr *int64, old, new int64) bool
atomic.CompareAndSwapUintptr(addr *uintptr, old, new uintptr) bool
atomic.CompareAndSwapPointer(addr *unsafe.Pointer, old, new unsafe.Pointer) bool
- 1
- 2
- 3
- 4
- 5
- 6
原子导出值
导出变量当前的值。
函数原型:
atomic.LoadUint32(addr *uint32) uint32
atomic.LoadUint64(addr *uint64) uint64
atomic.LoadInt32(addr *int32) int32
atomic.LoadInt64(addr *int64) int64
atomic.LoadUintptr(addr *uintptr) uintptr
atomic.LoadPointer(addr *unsafe.Pointer) unsafe.Pointer
- 1
- 2
- 3
- 4
- 5
- 6
原子导入值
赋予变量新值,而不管它原来是什么值。
函数原型:
atomic.StoreUint32(addr *uint32, val uint32)
atomic.StoreUint64(addr *uint64, val uint64)
atomic.StoreInt32(addr *int32, val int32)
atomic.StoreInt64(addr *int64, val int64)
atomic.StoreUintptr(addr *uintptr, val uintptr)
atomic.StorePointer(addr *unsafe.Pointer, val unsafe.Pointer)
- 1
- 2
- 3
- 4
- 5
- 6
原子交换值
赋予变量新值,同时返回变量的旧值。
函数原型:
atomic.SwapUint32(addr *uint32, new uint32) old uint32
atomic.SwapUint64(addr *uint64, new uint64) old uint64
atomic.SwapInt32(addr *int32, new int32) old int32
atomic.SwapInt64(addr *int64, new int64) old int64
atomic.SwapUintptr(addr *uintptr, new uintptr) old uintptr
atomic.SwapPointer(addr *unsafe.Pointer, new unsafe.Pointer) old unsafe.Pointer
sync/atomic 库使用小结相关推荐
- Go 学习笔记(23)— 并发(02)[竞争,锁资源,原子函数sync/atomic、互斥锁sync.Mutex]
本文参考 <Go 语言实战> 1. 竞争状态简述 如果两个或者多个 goroutine 在没有互相同步的情况下,访问某个共享的资源,并试图同时读和写这个资源,就处于相互竞争的状态,这种情况 ...
- 原子操作之sync/atomic
2019独角兽企业重金招聘Python工程师标准>>> 原子操作之sync/atomic 对于并发操作而言,原子操作是个非常现实的问题.典型的就是i++的问题. 当两个CPU同时对内 ...
- 算法:线性时间选择_机器学习必修课!scikit-learn 支持向量机算法库使用小结
本文从实践的角度对scikit-learn SVM算法库的使用做一个小结.scikit-learn SVM算法库封装了libsvm 和 liblinear 的实现,仅仅重写了算法了接口部分. 1. s ...
- Go原子操作 sync/atomic
sync/atomic包提供了底层的原子级内存操作,其执行过程不能被中断,这也就保证了同一时刻一个线程的执行不会被其他线程中断,也保证了多线程下数据操作的一致性. 操作的数据类型共有六种:int32, ...
- scikit-learn 支持向量机算法库使用小结
之前通过一个系列对支持向量机(以下简称SVM)算法的原理做了一个总结,本文从实践的角度对scikit-learn SVM算法库的使用做一个小结.scikit-learn SVM算法库封装了libsvm ...
- Golang 中 sync/atomic 包的原子操作
背景 Go中多协程的情况下, 要保证操作的原子性,一般要使用RWMutex或者Mutex, 但是锁使用起来比较复杂,还要考虑lock 和unlock 顺序和成对出现,不注意就容易出错. 于是在sync ...
- Python-time标准库知识小结
定义 time库是python中处理时间的标准库 时间获取 time()-------获取当前时间戳,浮点数形式 ctime()-------以可读的方式返回字符串时间 gmtime()------- ...
- Python-turtle标准库知识小结(python绘图工具)
_________________________________________________________________________ turtle:海龟(海龟库) 使用之前需要导入库:i ...
- Linux下动态库使用小结
1. 静态库和动态库的基本概念 静态库,是在可执行程序连接时就已经加入到执行码中,在物理上成为执行程序的一部分:使用静态库编译的程序运行时无需该库文件支持,哪里都可以用,但是生成的可执行文件较大.动态 ...
最新文章
- minicom使用总结
- 【蓄电池维护】第二弹 看似普通的测试仪表笔暗藏了什么玄机?
- 机器人学习--视觉定位数据集介绍
- list agg cause ORA-06502 PL/SQL: numeric or value error
- 进行优化处理(WinXP),加快系统运行速度
- 使用Qt Creator 2.60编写C/C++程序
- 平面设计素材模板| 还在为封面设计烦恼么?
- 【深入理解计算机系统-第二版】3.55习题
- 智能优化算法:金枪鱼群优化算法-附代码
- python关闭exe程序_Python打包exe程序一行简单的代码为什么就是那么多人不知道?...
- python中and和的区别_python中逻辑与或(and、or)和按位与或异或(amp;、|、^)区别...
- linux centos用户修改密码,centos怎么修改用户密码
- Android之——多媒体开发视频格式
- 样式小图标的三种处理方式
- 【认识 NVIDIA GPU】GPU相关基础概念介绍
- 用css实现文字抖动特效
- golang中的字符串
- 操作系统实验一到实验九合集(哈工大李治军)
- C#实现毫秒级计时器
- android java 线程通信_Android 线程间通信
热门文章
- 文件操作,读文件、写文件、获取文件长度、删除文件、判断文件格式等。
- oracle控制文件加载数据,关于SQLLOAD控制文件参数的问题
- python3未配置_python3安装文件遇到ssl未安装问题
- python爬虫基础教程1_Python爬虫系列(一)入门教学
- python连接redis集群如何释放内存_python 连接redis集群
- 数据分析技术 使用SQL和EXCEL工具 第2版 pdf
- BootKit病毒——“异鬼Ⅱ”的前世今生
- java中的与或运算
- Oracle 多表查询
- Codeforces Round #382 (Div. 2) D. Taxes 歌德巴赫猜想