2019独角兽企业重金招聘Python工程师标准>>>

原子操作之sync/atomic

对于并发操作而言,原子操作是个非常现实的问题。典型的就是i++的问题。 当两个CPU同时对内存中的i进行读取,然后把加一之后的值放入内存中,可能两次i++的结果,这个i只增加了一次。 如何保证多CPU对同一块内存的操作是原子的。 golang中sync/atomic就是做这个使用的。

具体的原子操作在不同的操作系统中实现是不同的。比如在Intel的CPU架构机器上,主要是使用总线锁的方式实现的。 大致的意思就是当一个CPU需要操作一个内存块的时候,向总线发送一个LOCK信号,所有CPU收到这个信号后就不对这个内存块进行操作了。 等待操作的CPU执行完操作后,发送UNLOCK信号,才结束。** 在AMD的CPU架构机器上就是使用MESI一致性协议的方式来保证原子操作。** 所以我们在看atomic源码的时候,我们看到它针对不同的操作系统有不同汇编语言文件。

如果我们善用原子操作,它会比锁更为高效。

CAS

原子操作中最经典的CAS(compare-and-swap)在atomic包中是Compare开头的函数。

func CompareAndSwapInt32(addr *int32, old, new int32) (swapped bool)
func CompareAndSwapInt64(addr *int64, old, new int64) (swapped bool)
func CompareAndSwapPointer(addr *unsafe.Pointer, old, new unsafe.Pointer) (swapped bool)
func CompareAndSwapUint32(addr *uint32, old, new uint32) (swapped bool)
func CompareAndSwapUint64(addr *uint64, old, new uint64) (swapped bool)
func CompareAndSwapUintptr(addr *uintptr, old, new uintptr) (swapped bool)

CAS的意思是判断内存中的某个值是否等于old值,如果是的话,则赋new值给这块内存。CAS是一个方法,并不局限在CPU原子操作中。 CAS比互斥锁乐观,但是也就代表CAS是有赋值不成功的时候,调用CAS的那一方就需要处理赋值不成功的后续行为了。

这一系列的函数需要比较后再进行交换,也有不需要进行比较就进行交换的原子操作。

func SwapInt32(addr *int32, new int32) (old int32)
func SwapInt64(addr *int64, new int64) (old int64)
func SwapPointer(addr *unsafe.Pointer, new unsafe.Pointer) (old unsafe.Pointer)
func SwapUint32(addr *uint32, new uint32) (old uint32)
func SwapUint64(addr *uint64, new uint64) (old uint64)
func SwapUintptr(addr *uintptr, new uintptr) (old uintptr)

增加或减少

对一个数值进行增加或者减少的行为也需要保证是原子的,它对应于atomic包的函数就是

func AddInt32(addr *int32, delta int32) (new int32)
func AddInt64(addr *int64, delta int64) (new int64)
func AddUint32(addr *uint32, delta uint32) (new uint32)
func AddUint64(addr *uint64, delta uint64) (new uint64)
func AddUintptr(addr *uintptr, delta uintptr) (new uintptr)

读取或写入

当我们要读取一个变量的时候,很有可能这个变量正在被写入,这个时候,我们就很有可能读取到写到一半的数据。 所以读取操作是需要一个原子行为的。在atomic包中就是Load开头的函数群。

func LoadInt32(addr *int32) (val int32)
func LoadInt64(addr *int64) (val int64)
func LoadPointer(addr *unsafe.Pointer) (val unsafe.Pointer)
func LoadUint32(addr *uint32) (val uint32)
func LoadUint64(addr *uint64) (val uint64)
func LoadUintptr(addr *uintptr) (val uintptr)

好了,读取我们是完成了原子性,那写入呢?也是同样的,如果有多个CPU往内存中一个数据块写入数据的时候,可能导致这个写入的数据不完整。 在atomic包对应的是Store开头的函数群。

func StoreInt32(addr *int32, val int32)
func StoreInt64(addr *int64, val int64)
func StorePointer(addr *unsafe.Pointer, val unsafe.Pointer)
func StoreUint32(addr *uint32, val uint32)
func StoreUint64(addr *uint64, val uint64)
func StoreUintptr(addr *uintptr, val uintptr)

=====END=====

转载于:https://my.oschina.net/xinxingegeya/blog/729204

原子操作之sync/atomic相关推荐

  1. Go原子操作 sync/atomic

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

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

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

  3. sync/atomic 库使用小结

    sync/atomic 库提供了原子操作的支持,原子操作直接有底层CPU硬件支持,因而一般要比基于操作系统API的锁方式效率高些.本文对 sync/atomic 中的基本操作进行一个简单的介绍. 原子 ...

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

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

  5. 走进C++11(三十七)原子操作之 std::atomic

    关注公众号获取更多信息: C++11提供了一个原子类型std::atomic<T>,可以使用任意类型作为模板参数,C++11内置了整型的原子变量,可以方便的使用原子变量,使用原子变量就不用 ...

  6. golangsha1解码_如何阅读Golang的源码?

    Go 的源码在安装包的 src/ 目录下.怎么看它的源码呢?直接看吧!没人教的情况下,只能自己撸了.当然,这种内容一般也不会有人教. 怎么撸? Go 源码中,应该可分为与语言息息相关的部分,和官方提供 ...

  7. go 原子操作 atomic

    1. 什么是原子操作 我们已经知道,原子操作即是进行过程中不能被中断的操作.也就是说,针对某个值的原子操作在被进行的过程当中,CPU绝不会再去进行其它的针对该值的操作.无论这些其它的操作是否为原子操作 ...

  8. go 原子操作 atomic的使用

    go语言提供的原子操作都是非侵入式的,它们由标准库代码包sync/atomic中的众多函数代表. 我们调用sync/atomic中的几个函数可以对几种简单的类型进行原子操作.这些类型包括int32,i ...

  9. 【并发编程】atomic 如何保证原子操作?分别用那几个方法?

    博主介绍: – 我是了 凡 微信公众号[了凡银河系]期待你的关注.未来大家一起加油啊~ 前言 之前学习了一些并发原语,已经认为差不多可以应对很多场景了,但是为什么还要学习原子操作呢?原来,在一些场景中 ...

最新文章

  1. RecyclerView 删除Item 以及删除整个RecyclerView
  2. 【多线程高并发】深入浅出原子性
  3. System.arraycopy用法
  4. SAP ABAP CDS view和 HANA CDS view的区别,CDS consumption view 和 BO view 的区别
  5. 一文带解读C# 动态拦截覆盖第三方进程中的函数(外挂必备)
  6. 2021年中国数字化采购研究报告
  7. sax 解析 xml
  8. 部分公务员已领数字货币工资,数字货币或年内扩大试点,支付宝、微信支付还会有优势吗?
  9. 软件开发过程中需要的文档汇总
  10. ENVI5.3下载和安装
  11. VC++ EasyPR车牌识别
  12. 贝叶斯估计、最大似然估计、最大后验概率估计
  13. CUDA error: invalid device ordinal
  14. python音乐编程_可以编程写音乐的python库musicpy教程(第一期) musicpy的数据结构...
  15. 找代做java,代做JAVA程序作业、代写学生信息查询系统、代做JAVA实验
  16. oracle driver class not found,错误 JDBC Driver class not found: oracle.jdbc.dirver.OracleDriver
  17. JVM虚拟机的理解(上)
  18. python 互质数_程序要计算最少数量的操作以使数字在Python中不是互质数?
  19. QT当中的【QSetting和.ini配置文件】以及【创建Resources.qrc】
  20. 小程序中this.setData的使用和注意事项

热门文章

  1. logback的使用和logback.xml详解
  2. 'python program'.count('p')的值是_如何用Python分析泰坦尼克号生还率?
  3. 树莓派控制多个舵机_树莓派控制SG90舵机
  4. php5.3源码,php5.3介绍
  5. java地铁线路规划_地铁线路规划——简单分析
  6. 两个大功率肖特基二极管的V-A特性
  7. 如何让自学更有效率?
  8. 简单BP网络识别数码表字符
  9. 基于级联FFT的广义互相关算法在声源定位中的应用
  10. 怎么解释卷积的两种不同运算结果长度的不同?