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 库使用小结相关推荐

  1. Go 学习笔记(23)— 并发(02)[竞争,锁资源,原子函数sync/atomic、互斥锁sync.Mutex]

    本文参考 <Go 语言实战> 1. 竞争状态简述 如果两个或者多个 goroutine 在没有互相同步的情况下,访问某个共享的资源,并试图同时读和写这个资源,就处于相互竞争的状态,这种情况 ...

  2. 原子操作之sync/atomic

    2019独角兽企业重金招聘Python工程师标准>>> 原子操作之sync/atomic 对于并发操作而言,原子操作是个非常现实的问题.典型的就是i++的问题. 当两个CPU同时对内 ...

  3. 算法:线性时间选择_机器学习必修课!scikit-learn 支持向量机算法库使用小结

    本文从实践的角度对scikit-learn SVM算法库的使用做一个小结.scikit-learn SVM算法库封装了libsvm 和 liblinear 的实现,仅仅重写了算法了接口部分. 1. s ...

  4. Go原子操作 sync/atomic

    sync/atomic包提供了底层的原子级内存操作,其执行过程不能被中断,这也就保证了同一时刻一个线程的执行不会被其他线程中断,也保证了多线程下数据操作的一致性. 操作的数据类型共有六种:int32, ...

  5. scikit-learn 支持向量机算法库使用小结

    之前通过一个系列对支持向量机(以下简称SVM)算法的原理做了一个总结,本文从实践的角度对scikit-learn SVM算法库的使用做一个小结.scikit-learn SVM算法库封装了libsvm ...

  6. Golang 中 sync/atomic 包的原子操作

    背景 Go中多协程的情况下, 要保证操作的原子性,一般要使用RWMutex或者Mutex, 但是锁使用起来比较复杂,还要考虑lock 和unlock 顺序和成对出现,不注意就容易出错. 于是在sync ...

  7. Python-time标准库知识小结

    定义 time库是python中处理时间的标准库 时间获取 time()-------获取当前时间戳,浮点数形式 ctime()-------以可读的方式返回字符串时间 gmtime()------- ...

  8. Python-turtle标准库知识小结(python绘图工具)

    _________________________________________________________________________ turtle:海龟(海龟库) 使用之前需要导入库:i ...

  9. Linux下动态库使用小结

    1. 静态库和动态库的基本概念 静态库,是在可执行程序连接时就已经加入到执行码中,在物理上成为执行程序的一部分:使用静态库编译的程序运行时无需该库文件支持,哪里都可以用,但是生成的可执行文件较大.动态 ...

最新文章

  1. minicom使用总结
  2. 【蓄电池维护】第二弹 看似普通的测试仪表笔暗藏了什么玄机?
  3. 机器人学习--视觉定位数据集介绍
  4. list agg cause ORA-06502 PL/SQL: numeric or value error
  5. 进行优化处理(WinXP),加快系统运行速度
  6. 使用Qt Creator 2.60编写C/C++程序
  7. 平面设计素材模板| 还在为封面设计烦恼么?
  8. 【深入理解计算机系统-第二版】3.55习题
  9. 智能优化算法:金枪鱼群优化算法-附代码
  10. python关闭exe程序_Python打包exe程序一行简单的代码为什么就是那么多人不知道?...
  11. python中and和的区别_python中逻辑与或(and、or)和按位与或异或(amp;、|、^)区别...
  12. linux centos用户修改密码,centos怎么修改用户密码
  13. Android之——多媒体开发视频格式
  14. 样式小图标的三种处理方式
  15. 【认识 NVIDIA GPU】GPU相关基础概念介绍
  16. 用css实现文字抖动特效
  17. golang中的字符串
  18. 操作系统实验一到实验九合集(哈工大李治军)
  19. C#实现毫秒级计时器
  20. android java 线程通信_Android 线程间通信

热门文章

  1. 文件操作,读文件、写文件、获取文件长度、删除文件、判断文件格式等。
  2. oracle控制文件加载数据,关于SQLLOAD控制文件参数的问题
  3. python3未配置_python3安装文件遇到ssl未安装问题
  4. python爬虫基础教程1_Python爬虫系列(一)入门教学
  5. python连接redis集群如何释放内存_python 连接redis集群
  6. 数据分析技术 使用SQL和EXCEL工具 第2版 pdf
  7. BootKit病毒——“异鬼Ⅱ”的前世今生
  8. java中的与或运算
  9. Oracle 多表查询
  10. Codeforces Round #382 (Div. 2) D. Taxes 歌德巴赫猜想