原子操作--sync/atomic的用法
golang 通过sync/atomic库来支持cpu和操作系统级别的原子操作。但是对要操作类型有如下要求
- int32, int64,uint32, uint64,uintptr,unsafe包中的Pointer。不过,针对unsafe.Pointer类型,该包并未提供进行原子加法操作的函数
sync/atomic 提供的原子操作有
- 加法(add), 比较并交换(compare and swap, 简称CAS),加载(load), 存储(store),交换(swap)
针对sync/atomic支持的类型,会有注入atomic.AddInt32这样的函数提供支持
import (
"fmt"
"sync/atomic"
)
func main() {
var a uint32 = 10
atomic.AddUint32(&a, 1)
fmt.Println(a)
// uint32需要一个非负整数,uint32(int32(-1)), 会被编译器报错,需要一个中间变量b来绕过
b := int32(-1)
atomic.AddUint32(&a, uint32(b))
fmt.Println(a)
// ^uint32(n-1), n为要减去的数
// 整数在计算机以补码形式存在,这里的异或求出来的补码与b的补码相同
atomic.AddUint32(&a, ^uint32(3-1))
fmt.Println(a)
}
上面的代码有几个点需要注意:
- 传递给atomic.AddUint32函数的必须是指针类型。同理,unsafe.Pointer也是如此
- 对于atomic.AddUint64函数做原子减法,有两种方法,具体看代码
sync/atomic 比较并交换操作与交换操作的异同:
- 比较并交换操作即CAS操作,是有条件的交换操作,只有在条件满足的情况下才会进行值的交换
func main() {
var a int32 = 0
go func() {
for {
fmt.Println(a)
// 当a == 10,就设置 a=0,并返回ture
if atomic.CompareAndSwapInt32(&a, 10, 0) {
fmt.Println("The second number has gone to zero.")
break
}
time.Sleep(time.Millisecond * 500)
}
}()
for {
a++
if a >10 {
break
}
time.Sleep(time.Millisecond * 600)
}
}
sync/automic.Value
- sync/automic.Value相当于一个容器,可以被用来"原子地"存储和加载任意的值
atomic.Value使用事项
- 不用初始化,声明后即可使用。有两个指针方法Store和Load
- atomic.Value类型属于结构体类型,而结构体属于值类型,因此对该值的赋值,都会产生新的副本。
- 不能存储nil。
- 第一个存入的值类型,决定了后续atomic.Value可以存入的值
原子操作--sync/atomic的用法的更多相关文章
- golang sync/atomic
刚刚学习golang原子操作处理的时候发现github上面一个比较不错的golang学习项目 附上链接:https://github.com/polaris1119/The-Golang-Standa ...
- 原子操作(atomic operation)
深入分析Volatile的实现原理 引言 在多线程并发编程中synchronized和Volatile都扮演着重要的角色,Volatile是轻量级的synchronized,它在多处理器开发中保证了共 ...
- golang语言中sync/atomic包的学习与使用
package main; import ( "sync/atomic" "fmt" "sync" ) //atomic包提供了底层的原子级 ...
- Java 并发系列之九:java 原子操作类Atomic(13个)
1. 原子更新基本类型类 2. 原子更新数组 3. 原子更新引用 4. 原子更新属性 5. txt java 原子操作类Atomic 概述 java.util.concurrent.atomic里的原 ...
- java架构之路(多线程)原子操作,Atomic与Unsafe魔术类
这次不讲原理了,主要是一些应用方面的知识,和上几次的JUC并发编程的知识点更容易理解. 知识回顾: 上次主要说了Semaphore信号量的使用,就是一个票据的使用,我们举例了看3D电影拿3D眼镜的例子 ...
- 探究Java如何实现原子操作(atomic operation)
1. 让我们首先了解下java 中 Volatile 关键字 Volatile可实现java内存模型当中的可见性, java内存模型的可见性: 可见性,是指线程之间的可见性,一个线程修改的状态对另一个 ...
- C++11中的原子操作(atomic operation)
所谓的原子操作,取的就是“原子是最小的.不可分割的最小个体”的意义,它表示在多个线程访问同一个全局资源的时候,能够确保所有其他的线程都不在同一时间内访问相同的资源.也就是他确保了在同一时刻只有唯一的线 ...
- C++11中的原子操作(atomic operation)(转)
所谓的原子操作,取的就是“原子是最小的.不可分割的最小个体”的意义,它表示在多个线程访问同一个全局资源的时候,能够确保所有其他的线程都不在同一时间内访问相同的资源.也就是他确保了在同一时刻只有唯一的线 ...
- [Go] sync.Once 的用法
sync.Once.Do(f func()) 是一个非常有意思的东西,能保证 once 只执行一次,无论你是否更换 once.Do(xx) 这里的方法,这个 sync.Once块 只会执行一次. pa ...
随机推荐
- ios 基础知识篇 堆和栈的区别
前言 堆和栈是什么?有什么区别?是干嘛的? 内存管理 移动设备的内存及其有限,每一个APP所能占用的内存是有限制的 (吐槽一下:iPhone6s还是16G起步,还好我也买不起->_-> 扯 ...
- 2019.01.21 NOIP训练 可持久化序列【模板】(可持久化treap)
传送门 题意简述:支持在把某个数插入到某版本的第k个位置,删除某版本第k个数,询问第k个数. 思路:用可持久化treaptreaptreap维护区间第kkk个位置的数是啥就可以了. 代码
- 2018.12.19 atcoder Iroha and a Grid(组合数学)
传送门 组合数学好题. 给你一个hhh行www列的网格,其中左下角aaa行bbb列不能走,问从左上角走到右下角有多少种走法(每次只能向右或者向下) 我们考虑分步计数. 我们一共能走的区域是总网格区域去 ...
- 补全爬取的url
有时爬取到的href不全,如href=‘/11031/’解决方法:from urllib import parseurl=parse.urljoin(response.url,get_url)resp ...
- spring mvc 文件上传工具类
虽然文件上传在框架中,已经不是什么困难的事情了,但自己还是开发了一个文件上传工具类,是基于springmvc文件上传的. 工具类只需要传入需要的两个参数,就可以上传到任何想要上传的路径: 参数1:Ht ...
- Andorid第一次作业
一.作业截图 二.项目路径 https://git.coding.net/bestimbalance/Android.git 三.小组成员 邢路: https://www.cnblogs.com/x ...
- GetWindowRect
示例代码: CRect rect; GetDlgItem(IDC_STATIC_VIEW)->GetWindowRect(&rect); int width=rect.Width(); ...
- BUG 图片元素img下 高度超出 出现多余空白
BUG 图片元素img下 高度超出 出现多余空白 1.将图片转换为块级对象 即,设置img为“display:block;”. 2.设置图片的垂直对齐方式 即设置图片的vertical-align ...
- 4、C语言的编译过程链
在学校学C语言的时候,很多人都不是很注重编译过程链,但是其实编译过程是项目过程中很重要的一部分,有时候有些语法诸如static.volatile等关键词不理解时大多数都是对整个C语言编译链没有进行过详 ...
- 距离LCA离线算法Tarjan + dfs + 并查集
距离B - Distance in the Tree 还是普通的LCA但是要求的是两个节点之间的距离,学到了一些 一开始我想用带权并查集进行优化,但是LCA合并的过程晚于离线计算的过程,所以路径长度会 ...