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(addruint32) (val uint32)<br>func LoadUint64(addruint64) (val uint64)<br>func LoadUintptr(addruintptr) (val uintptr)<br>func LoadPointer(addrunsafe.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,理论上两个线程运 ...
随机推荐
- 关于c++、go、nodejs、python的计算性能测试,结果令人惊讶
计算性能在计算密集型的服务上,是非常重要的, 一直以为,在计算性能上,肯定是C++ > go > nodejs >= python 但测试结果却让人大跌眼镜!!! 实际的结果是: ...
- 【LeetCode】1114. Print in Order 解题报告(C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 mutex锁 promise/future 日期 题 ...
- 【九度OJ】题目1198:a+b 解题报告
[九度OJ]题目1198:a+b 解题报告 标签(空格分隔): 九度OJ 原题地址:http://ac.jobdu.com/problem.php?pid=1198 题目描述: 实现一个加法器,使其能 ...
- 【LeetCode】783. Minimum Distance Between BST Nodes 解题报告(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 中序遍历 日期 题目地址:https://leetc ...
- 【LeetCode】60. Permutation Sequence 解题报告(Python & C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 日期 题目地址:https://leetcode.c ...
- C. Arpa's loud Owf and Mehrdad's evil plan
C. Arpa's loud Owf and Mehrdad's evil plan time limit per test 1 second memory limit per test 256 me ...
- GCD is Funny(hdu 5902)
GCD is Funny Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Tota ...
- Sentry 开发者贡献指南 - SDK 开发(事件负载)
内容整理自官方开发文档 系列 Docker Compose 部署与故障排除详解 1 分钟快速使用 Docker 上手最新版 Sentry-CLI - 创建版本 快速使用 Docker 上手 Sentr ...
- webSocket 与HTTP
WebSocket 协议在2008年诞生,2011年成为国际标准.现在所有浏览器都已经支持了.WebSocket 的最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真 ...
- Java EE数据持久化框架 • 【第3章 MyBatis高级映射】
全部章节 >>>> 本章目录 3.1 一对一映射 3.1.1 自动化一对一映射 3.1.2 标签配置一对一映射 3.1.3 标签配置一对一映射 3.1.4 实践练习 3.2 ...