golang中的原子操作atomic包
1. 概念
原子操作 atomic 包
加锁操作涉及到内核态的上下文切换,比较耗时,代价高,
针对基本数据类型我们还可以使用原子操作来保证并发的安全,
因为原子操作是go语言提供的方法,我们在用户态就可以完成,因此性能比加锁操作更好
go语言的原子操作由内置的库 sync/atomic 完成
2. atomic包
方法 | 解释 |
---|---|
func LoadInt32(addr int32) (val int32) func LoadInt64(addr `int64 ) (val int64)<br>func LoadUint32(addr uint32) (val uint32)<br>func LoadUint64(addr uint64) (val uint64)<br>func LoadUintptr(addr uintptr) (val uintptr)<br>func LoadPointer(addr unsafe.Pointer`) (val unsafe.Pointer) |
读取操作 |
func StoreInt32(addr *int32 , val int32)func StoreInt64(addr *int64 , val int64)func StoreUint32(addr *uint32 , val uint32)func StoreUint64(addr *uint64 , val uint64)func StoreUintptr(addr *uintptr , val uintptr)func StorePointer(addr *unsafe.Pointer , val unsafe.Pointer) |
写入操作 |
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) |
修改操作 |
func SwapInt32(addr *int32 , new int32) (old int32)func SwapInt64(addr *int64 , new int64) (old int64)func SwapUint32(addr *uint32 , new uint32) (old uint32)func SwapUint64(addr *uint64 , new uint64) (old uint64)func SwapUintptr(addr *uintptr , new uintptr) (old uintptr)func SwapPointer(addr *unsafe.Pointer , new unsafe.Pointer) (old unsafe.Pointer) |
交换操作 |
func CompareAndSwapInt32(addr *int32 , old, new int32) (swapped bool)func CompareAndSwapInt64(addr *int64 , old, new int64) (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)func CompareAndSwapPointer(addr *unsafe.Pointer , old, new unsafe.Pointer) (swapped bool) |
3. 案例比较互斥锁和原子操作的性能
package main import (
"fmt"
"sync"
"sync/atomic"
"time"
) var (
x int64
mx sync.Mutex
wg sync.WaitGroup
) // 普通函数,并发不安全
func Add() {
x++
wg.Done()
}
// 互斥锁,并发安全,性能低于原子操作
func MxAdd() {
mx.Lock()
x++
mx.Unlock()
wg.Done()
}
// 原子操作,并发安全,性能高于互斥锁,只针对go中的一些基本数据类型使用
func AmAdd() {
atomic.AddInt64(&x, 1)
wg.Done()
} func main() {
// 原子操作 atomic 包
// 加锁操作涉及到内核态的上下文切换,比较耗时,代价高,
// 针对基本数据类型我们还可以使用原子操作来保证并发的安全,
// 因为原子操作是go语言提供的方法,我们在用户态就可以完成,因此性能比加锁操作更好
// go语言的原子操作由内置的库 sync/atomic 完成 start := time.Now()
for i := 0; i < 10000; i++ {
wg.Add(1)
//go Add() // 普通版Add函数不是并发安全的
//go MxAdd() // 加锁版Add函数,是并发安全的,但是加锁性能开销大
go AmAdd() // 原子操作版Add函数,是并发安全的,性能优于加锁版
} end := time.Now()
wg.Wait()
fmt.Println(x)
fmt.Println(end.Sub(start)) }
atomic包提供了底层的原子级内存操作,对于同步算法的实现很有用,这些函数必须谨慎的保证正确使用,除了某些特殊的底层应用,使用通道或者sync包的函数/类型实现同步更好
golang中的原子操作atomic包的更多相关文章
- 什么是Java中的原子操作( atomic operations)
1.啥是java的原子性 原子性:即一个操作或者多个操作 要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行. 一个很经典的例子就是银行账户转账问题: 比如从账户A向账户B转1000元,那么 ...
- golang语言中sync/atomic包的学习与使用
package main; import ( "sync/atomic" "fmt" "sync" ) //atomic包提供了底层的原子级 ...
- golang中tcp socket粘包问题和处理
转自:http://www.01happy.com/golang-tcp-socket-adhere/ 在用golang开发人工客服系统的时候碰到了粘包问题,那么什么是粘包呢?例如我们和客户端约定数据 ...
- golang中的net/rpc包
本文先介绍RPC,然后go原生对RPC的使用,之后是介绍go语言中有哪些RPC框架以及一些其他常见的框架,最后是探究go语言中rpc的源码. (1)首先介绍下什么RPC? (2)RPC可以做什么? ( ...
- Java中的Atomic包
Atomic包的作用 方便程序员在多线程环境下,无锁的进行原子操作 Atomic包核心 Atomic包里的类基本都是使用Unsafe实现的包装类,核心操作是CAS原子操作: 关于CAS compare ...
- java.util.concurrent.atomic 包详解
Atomic包的作用: 方便程序员在多线程环境下,无锁的进行原子操作 Atomic包核心: Atomic包里的类基本都是使用Unsafe实现的包装类,核心操作是CAS原子操作 关于CAS compar ...
- golang中并发sync和channel
golang中实现并发非常简单,只需在需要并发的函数前面添加关键字"go",但是如何处理go并发机制中不同goroutine之间的同步与通信,golang 中提供了sync包和channel ...
- 24.Java中atomic包中的原子操作类总结
1. 原子操作类介绍 在并发编程中很容易出现并发安全的问题,有一个很简单的例子就是多线程更新变量i=1,比如多个线程执行i++操作,就有可能获取不到正确的值,而这个问题,最常用的方法是通过Synchr ...
- Java中Atomic包的实现原理及应用
1. 同步问题的提出 假设我们使用一个双核处理器执行A和B两个线程,核1执行A线程,而核2执行B线程,这两个线程现在都要对名为obj的对象的成员变量i进行加1操作,假设i的初始值为0,理论上两个线程运 ...
随机推荐
- Linux(centos7)安装redis并设置redis开机自启动
1.下载redis安装包 wget http://download.redis.io/releases/redis-4.0.6.tar.gz 2.解压安装包 tar -zxvf redis-4.0.6 ...
- es(elasticsearch)安装IK中文分词器
IK压缩包下载地址:https://github.com/medcl/elasticsearch-analysis-ik/releases?after=v6.7.0,需要下载对应的版本 我也上传了 h ...
- c++11之std::bind简单使用
note 更多用法,请参考: cppreference 用的少,容易忘. 我的理解 类似延迟计算. 比如,回调函数,将回调函数传入后,回调函数不一定马上被调用. 它是一个模板类,调用后将生成一个新的调 ...
- C语言之可变长参数格式化
概述 本文演示环境: win10 + Vs2015 可变长参数格式化 两个概念: 1. 参数长度不定, 2. 参数格式化. 使用函数 vsnprintf 结合 va_list. 源码 写好了函数, 照 ...
- github源码下载总结
总结 下面来自我的经验,仅作参考. 下载时间选择 千万不要选择 晚上下载.下午7点后就不要从github上传或者下载代码,我用的是电信,踩坑: 这段时间后到第二天早上7点之前,这段时间内的上传和下载只 ...
- 【LeetCode】540. Single Element in a Sorted Array 解题报告(Python & C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 解题方法 方法一:异或 方法二:判断相邻元素是否相等 方法三:二分查找 ...
- idea使用教程-Module的概念和使用
一.IDEA页面展示 [1]项目下内容: ➢工程下的src类似于Eclipse下的src目录,用于存放代码.. ➢工程下的.idea 和TestProject.iml文件都是IDEA工程特有的.类似于 ...
- 「Codeforces 79D」Password
Description 有一个 01 序列 \(a_1,a_2,\cdots,a_n\),初始时全为 \(0\). 给定 \(m\) 个长度,分别为 \(l_1\sim l_m\). 每次可以选择一个 ...
- 一个简单的js时钟
演示地址 代码 <html> <head> <title> Nonove js clock 时钟 </title> <script type=&q ...
- Java初学者作业——使用switch结构实现一个简单的购物计划
返回本章节 返回作业目录 需求说明: 使用switch结构实现一个购物计划,计划为:星期一.星期三.星期五购买伊利牛奶和面包,星期二.星期四购买苹果和香蕉,星期六.星期日购买啤酒和周黑鸭. 实现思路: ...