goland -sync/atomic原子操作小结
作者:Jeff的技术栈 发布时间:2024-04-26 17:20:08
1.go已经提供了锁,为什么还需要atomic原子操作?
1.加锁代价比较高,耗时多,需要上下文切换。加锁解锁在代码层实现,而代码是运行在用户态空间中,对底层进行操作时需要从用户态空间切换到内核空间,再由内核操作底层资源。耗时多
2.原子操作在用户态可以完成,性能比互斥锁高。原子操作在cpu层面支持的,cpu可以直接操作底层资源
3.原子操作需求步骤简单,无需加锁解锁步骤
2.atomic原子操作为什么比mutex快?
1.原子操作快,是因为依赖于cpu指令,而不是依赖外部锁。不会额外的上下文切换
2.原子操作能够保证执行期间是连续且不会被中断(变量不会被其他修改,mutex可能存在被其他修改的情况)
3.CAS
CAS是cpu硬件同步原语,是Compare And Swap的缩写(比较并交换),原子操作中CAS,再sync/atomic包中,全部以ComparAndSwap开头的函数名都是CAS操作
go中CAS操作,是借用CPU提供的原子性指令来实现。CAS操作修改共享变量时,不需要对共享变量加锁,而是通过类似乐观锁的方式进行检查,本质还是不断的占用CPU资源换取加锁带来的开销(如上下文切换时间开销)。
原子操作优势:
可以在不形成临界区和创建互斥量的情况下完成并发安全的值替换操作。这可以大大的减少同步对程序性能的损耗。
原子操作劣势:
在 * 作值被频繁的变更的情况下,CAS操作并不那么容易成功。因为需要对ild值进行匹配,只有匹配成功了才进行下一步的修改。
当前atmomic包有以下几种原子操作:
Add,ComparAndSwap,Load,Store,Swap
4.互斥锁与原子操作区别
互斥锁目的:互斥锁是用来保护一段逻辑的,保证并发安全。(比如操作数据库保护)
原子操作目的:原子操作作用于一个变量的更新保护,保证并发安全(比如操作数据库不能原子操作)
mutex底层实现:mutex由操作系统的调度器实现
原子操作底层实现:由底层硬件指令直接提供支持,这些指令在执行过程中不允许中断,因此原子操作可以在无锁的情况下保证并发安全,性能随cpu的数量增多而线性扩展。
5.原子操作方法
5.1 atomic.AddInt32--增减
增减,操作方法的命名方式为AddXXX,保证对操作数进行原子的增减,支持的类型为int32、int64、uint32、uint64、uintptr,使用时以AddXXX就是对应的操作方法。
//加
func demo() {
var count int32 = 0
atomic.AddInt32(&count, 10)
fmt.Println(count) //10
}
//减
func demo() {
var count int32 = 0
atomic.AddInt32(&count, -10)
fmt.Println(count) //-10
}
锁和原子操作对比:
//Mutex锁
func demo1() {
sta := time.Now().Unix()
count := 0
mux := sync.Mutex{}
wg := sync.WaitGroup{}
for i := 0; i < 10000; i++ {
wg.Add(1)
go func() {
defer wg.Done()
for j := 0; j < 10000; j++ {
mux.Lock()
count++
mux.Unlock()
}
}()
}
wg.Wait()
fmt.Println(count) //100000000
fmt.Println(time.Now().Unix() - sta) //10秒
}
//atomic原子操作:快2倍不止
func demo2() {
sta := time.Now().Unix()
wg := sync.WaitGroup{}
var count int32 = 0
for i := 0; i < 10000; i++ {
wg.Add(1)
go func() {
defer wg.Done()
for j := 0; j < 10000; j++ {
atomic.AddInt32(&count, 1)
}
}()
}
wg.Wait()
fmt.Println(count) //100000000
fmt.Println(time.Now().Unix() - sta) //4秒
}
5.2 CAS-atomic.CompareAndSwapInt32--比较并替换
CompareAndSwap:比较并替换,类似乐观锁,先比较下old值与当前值是否一致,一致则把new的值替换
操作方法的命名方式为CompareAndSwapXXX
//true
func demo3() {
var count int32 = 0
boo := atomic.CompareAndSwapInt32(&count, 0, 100)
fmt.Println(count) //100
fmt.Println(boo) //true
}
//false
func demo3() {
var count int32 = 0
boo := atomic.CompareAndSwapInt32(&count, 10, 100)
fmt.Println(count) //0
fmt.Println(boo) //false
}
5.3 atomic.StoreInt32--写操作
func demo3() {
var count int32 = 0
atomic.StoreInt32(&count, 666)
fmt.Println(count) //666
}
5.4 atomic.LoadInt32--读操作
func demo3() {
var count int32 = 0
atomic.StoreInt32(&count, 666)
val := atomic.LoadInt32(&count)
fmt.Println(val) //666
}
5.5 atomic.SwapInt32--直接交换
atomic.SwapInt32:直接交换,并返回交换前的值
func demo3() {
var count int32 = 0
old := atomic.SwapInt32(&count, 100)
fmt.Println(old) //0
fmt.Println(count) //100
}
来源:https://www.cnblogs.com/guyouyin123/p/16565192.html
猜你喜欢
- 安装配置MongoDB驱动安装驱动go get -u github.com/mongodb/mongo-go-driver初始化模块go m
- MySQL加密和解密实例详解数据加密、解密在安全领域非常重要。对程序员而言,在数据库中以密文方式存储用户密码对入侵者剽窃用户隐私意义重大。有
- 这是一个很和谐很实用的网站管理程序,和我以前介绍的服务器管理程序不同的是,这个程序只有一个功能,就是实现远程Web方式删除文件(实际上是重命
- 本文实例为大家分享了python3实现多张图片附件邮件发送的具体代码,供大家参考,具体内容如下直接上代码,没有注释!from email.m
- SAX是一种基于事件驱动的API。利用SAX解析XML文档牵涉到两个部分:解析器和事件处理器。解析器负责读取XML文档,并向事件处理器发送事
- 本文实例讲述了Python实现删除文件中含指定内容的行。分享给大家供大家参考,具体如下:#!/bin/env pythonimport sh
- 前言在跟进需求的时候,往往涉及到测试,特别是需要用到身份信息的时候,总绕不开身份证号码这个话题。之前在跟一个互联网产品的时候,需要很多身份证
- 问题描述当前使用的PyCharm社区版版本号2022.1.2,配置镜像源时,没有manage repositories解决方案:镜像源:清华
- 首先,看看本文所面向的应用场景:我们有一个数据集df,现在想统计数据中某一列每个元素的出现次数。这个在我们前面文章《如何画直方图》中已经介绍
- 实验环境1.安装Python 3.72.安装requests, bs4,pymysql 模块实验步骤1.安装环境及模块可参考https://
- 本文实例讲述了python实现批量获取指定文件夹下的所有文件的厂商信息的方法。分享给大家供大家参考。具体如下:功能代码如下:import o
- char(n)是定长格式,格式为char(n)的字段固定占用n个字符宽度,如果实际存放的数据长度超过n将被截取多出部分,如果长度小于n就用空
- 此版本是始终只有最新的一版(我自己的用的是版本是每天都有一个备份) declare @DBName varchar(200) set @DB
- MS SQL Server查询优化方法查询速度慢的原因很多,常见如下几种 1、没有索引或者没有用到索引(这是查询慢最常见的问题,是程序设计的
- 前言在之前介绍fixture的文章中,我们使用到了conftest.py文件,那么conftest.py文件到底该如何使用呢,下面我们就来详
- 浅谈NumPy中的维度AxisNumPy中的维度是一个很重要的概念,很多函数的参数都需要给定维度Axis,如何直观的理解维度呢?我们首先以二
- 阅读上一章:Css布局Chapter 13 为文字指定样式我想以一章的篇幅来讨论用CSS设定文字样式的做法是个好点子.一般处理文字内容大概是
- 1. 系统盘清理说明win7 80G的系统盘,随着使用时间的增加,空间越来越小,只剩不到2G,随计划清理系统盘数据1. maven 下载的j
- 前言学习Python的初衷是因为它的实践的便捷性,几乎计算机上能完成的各种操作都能在Python上找到解决途径。平时工作需要在线学习。而在线
- 一、shutil模块(了解):高级的文件、文件夹、压缩包处理模块。import shutil# shutil.copyfileobj(fsr