当前位置: 首页 > news >正文

Go 原子操作有哪些?

Go atomic包是最轻量级的锁(也称无锁结构),可以在不形成临界区和创建互斥量的情况下完成并发安全的值替换操作,不过这个包只支持int32/int64/uint32/uint64/uintptr这几种数据类型的一些基础操作(增减、交换、载入、存储等)

概念

原子操作仅会由一个独立的CPU指令代表和完成。原子操作是无锁的,常常直接通过CPU指令直接实现。 事实上,其它同步技术的实现常常依赖于原子操作。

使用场景

当我们想要对某个变量并发安全的修改,除了使用官方提供的 mutex,还可以使用 sync/atomic 包的原子操作,它能够保证对变量的读取或修改期间不被其他的协程所影响。

atomic 包提供的原子操作能够确保任一时刻只有一个goroutine对变量进行操作,善用 atomic 能够避免程序中出现大量的锁操作。

常见操作

  • 增减Add
  • 载入Load
  • 比较并交换CompareAndSwap
  • 交换Swap
  • 存储Store

atomic 操作的对象是一个地址,你需要把可寻址的变量的地址作为参数传递给方法,而不是把变量的值传递给方法

下面将分别介绍这些操作:

增减操作

此类操作的前缀为 Add

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)

需要注意的是,第一个参数必须是指针类型的值,通过指针变量可以获取被操作数在内存中的地址,从而施加特殊的CPU指令,确保同一时间只有一个goroutine能够进行操作。

使用举例:

func add(addr *int64, delta int64) {atomic.AddInt64(addr, delta) //加操作fmt.Println("add opts: ", *addr)
}

载入操作

此类操作的前缀为 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)// 特殊类型: Value类型,常用于配置变更
func (v *Value) Load() (x interface{}) {}

载入操作能够保证原子的读变量的值,当读取的时候,任何其他CPU操作都无法对该变量进行读写,其实现机制受到底层硬件的支持。

使用示例:

func load(addr *int64) {fmt.Println("load opts: ", atomic.LoadInt64(&opts))
}

比较并交换

此类操作的前缀为 CompareAndSwap, 该操作简称 CAS,可以用来实现乐观锁

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)

该操作在进行交换前首先确保变量的值未被更改,即仍然保持参数 old 所记录的值,满足此前提下才进行交换操作。CAS的做法类似操作数据库时常见的乐观锁机制。

需要注意的是,当有大量的goroutine 对变量进行读写操作时,可能导致CAS操作无法成功,这时可以利用for循环多次尝试。

使用示例:

func compareAndSwap(addr *int64, oldValue int64, newValue int64) {if atomic.CompareAndSwapInt64(addr, oldValue, newValue) {fmt.Println("cas opts: ", *addr)return}
}

交换

此类操作的前缀为 Swap

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)

相对于CAS,明显此类操作更为暴力直接,并不管变量的旧值是否被改变,直接赋予新值然后返回背替换的值。

func swap(addr *int64, newValue int64) {atomic.SwapInt64(addr, newValue)fmt.Println("swap opts: ", *addr)
}

存储

此类操作的前缀为 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)// 特殊类型: Value类型,常用于配置变更
func (v *Value) Store(x interface{})

此类操作确保了写变量的原子性,避免其他操作读到了修改变量过程中的脏数据。

func store(addr *int64, newValue int64) {atomic.StoreInt64(addr, newValue)fmt.Println("store opts: ", *addr)
}

本文节选于Go合集《常见面试题汇总》
GOLANG ROADMAP一个专注Go语言学习、求职的社区。

相关文章:

Go 原子操作有哪些?

Go atomic包是最轻量级的锁(也称无锁结构),可以在不形成临界区和创建互斥量的情况下完成并发安全的值替换操作,不过这个包只支持int32/int64/uint32/uint64/uintptr这几种数据类型的一些基础操作(增减、交换、载入、存…...

爬虫知识--02

免费代理池搭建 # 代理有免费和收费代理 # 代理有http代理和https代理 # 匿名度: 高匿:隐藏访问者ip 透明:服务端能拿到访问者ip 作为后端,如何拿到使用代理人的ip 请求头中:x-forwor…...

SCI一区 | Matlab实现GAF-PCNN-MSA格拉姆角场和双通道PCNN融合注意力机制的多特征分类预测

SCI一区 | Matlab实现GAF-PCNN-MSA格拉姆角场和双通道PCNN融合注意力机制的多特征分类预测 目录 SCI一区 | Matlab实现GAF-PCNN-MSA格拉姆角场和双通道PCNN融合注意力机制的多特征分类预测效果一览基本介绍模型描述程序设计参考资料 效果一览 基本介绍 1.【SCI一区级】Matlab实…...

Observability:使用 OpenTelemetry 和 Elastic 监控 OpenAI API 和 GPT 模型

作者: 来自 Elastic David Hope ChatGPT 现在非常火爆,甚至席卷了整个互联网。 作为 ChatGPT 的狂热用户和 ChatGPT 应用程序的开发人员,我对这项技术的可能性感到非常兴奋。 我看到的情况是,基于 ChatGPT 的解决方案将会呈指数级…...

靡语IT:Vue精讲(一)

Vue简介 发端于2013年的个人项目,已然成为全世界三大前端框架之一,在中国大陆更是前端首选。 它的设计思想、编码技巧也被众多的框架借鉴、模仿。 纪略 2013年,在Google工作的尤雨溪,受到Angular的启发,从中提取自…...

vue3 toRefs之后的变量修改方法

上效果 修改值需要带上解构之前的对象名obj&#xff0c; changeName:()>{ // toRefs 解决后变量修改值方法&#xff1a; 解构前变量.字段新值 obj.name FEIFEI; } } 案例源码 <!DOCTYPE html> <html> <head><me…...

【教程】详解相机模型与坐标转换

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhang.cn] 由于复制过来&#xff0c;如果有格式问题&#xff0c;推荐大家直接去我原网站上查看&#xff1a; 相机模型与坐标转换 - 生活大爆炸 目录 经纬度坐标系 转 地球直角坐标系大地直角坐标系 转 经纬度坐标系地理坐标…...

171基于matlab的随机共振微弱信号检测

基于matlab的随机共振微弱信号检测&#xff0c;随机共振描述了过阻尼布朗粒子受周期性信号和随机噪声的共同作用下,在非线性双稳态系统中所发生的跃迁现象. 随机共振可用于弱信号的检测。程序已调通&#xff0c;可直接运行。...

petalinux_zynq7 驱动DAC以及ADC模块之三:实现C语言API并编译出库被python调用

前文&#xff1a; petalinux_zynq7 C语言驱动DAC以及ADC模块之一&#xff1a;建立IPhttps://blog.csdn.net/qq_27158179/article/details/136234296petalinux_zynq7 C语言驱动DAC以及ADC模块之二&#xff1a;petalinuxhttps://blog.csdn.net/qq_27158179/article/details/1362…...

NXP实战笔记(五):S32K3xx基于RTD-SDK在S32DS上配置ADC的硬件触发同步采样与软件采样过程

目录 1、概述 1.1、软件触发 1.2、硬件触发 - BCTU 1.3、硬件触发 - TRGMUX 1.4、ADC的校准 1.5、ADC时钟配置 2、BTCU硬件触发ADC的SDK配置 3、软件触发ADC 3.1、选择相应Port作为ADC的输入 3.2、ADC配置 3.3、代码示例 1、概述 恩智浦 S32K3xx 系列汽车微控制器…...

pikachu靶场-CSRF

CSRF: 介绍&#xff1a; Cross-site request forgery简称为"CSRF”。 在CSF的攻击场景中攻击者会伪造一个请求&#xff08;这个请求一般是一个链接&#xff09; 然后欺骗目标用户进行点击&#xff0c;用户一旦点击了这个请求&#xff0c;整个攻击也就完成了&#xff0…...

【结合OpenAI官方文档】解决Chatgpt的API接口请求速率限制

OpenAI API接口请求速率限制 速率限制以五种方式衡量&#xff1a;RPM&#xff08;每分钟请求数&#xff09;、RPD&#xff08;每天请求数&#xff09;、TPM&#xff08;每分钟令牌数&#xff09;、TPD&#xff08;每天令牌数&#xff09;和IPM&#xff08;每分钟图像数&#x…...

C语言实现基础数据结构——栈

目录 栈 栈的实现 数组栈 数组栈的实现 栈的初始化 栈的销毁 数据入栈 判断栈是否为空 数据出栈 获取栈顶元素 获取栈内数据个数 项目实现 栈的基础练习 有效的括号 栈 栈是一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的…...

船舶制造5G智能工厂数字孪生可视化平台,推进船舶行业数字化转型

船舶制造5G智能工厂数字孪生可视化平台&#xff0c;推进船舶行业数字化转型。随着数字化时代的到来&#xff0c;船舶行业正面临着前所未有的机遇与挑战。为了适应这一变革&#xff0c;船舶制造企业需要加快数字化转型的步伐&#xff0c;提高生产效率、降低成本并增强市场竞争力…...

【网络编程】okhttp深入理解

newCall 实际上是创建了一个 RealCall 有三个参数&#xff1a;OkHttpClient&#xff08;通用配置&#xff0c;超时时间等&#xff09; Request(Http请求所用到的条件&#xff0c;url等) 布尔变量forWebSocket&#xff08;webSocket是一种应用层的交互方式&#xff0c;可双向交互…...

大功率厚膜电阻器制造 – 优化性能?

通过优化工业大功率电阻器制造工艺&#xff0c;制造商可以提高电阻器的性能和可靠性、容差、额定电压、TCR、稳定性和额定功率。 在本文中&#xff0c;我们将介绍工业功率电阻器的制造过程。我们讨论了材料选择和生产技术及其对性能的潜在影响。 完美的电阻器 在其整个使用寿…...

ElasticStack安装(windows)

官网 : Elasticsearch 平台 — 大规模查找实时答案 | Elastic Elasticsearch Elastic Stack(一套技术栈) 包含了数据的整合 >提取 >存储 >使用&#xff0c;一整套! 各组件介绍: beats 套件:从各种不同类型的文件/应用中采集数据。比如:a,b,cd,e,aa,bb,ccLogstash:…...

gitlab的使用

前一篇文章我们已经知道Git人人都是中心&#xff0c;那他们怎么交互数据呢&#xff1f; • 使用GitHub或者码云等公共代码仓库 • 使用GitLab私有仓库 目录 一、安装配置gitlab 安装 初始化 这里初始化完成以后需要记住一个初始密码 查看状态 二、使用浏览器访问&#xf…...

基于springboot+vue的植物健康系统(前后端分离)

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…...

Python爬虫实战入门:爬取360模拟翻译(仅实验)

文章目录 需求所需第三方库requests 实战教程打开网站抓包添加请求头等信息发送请求&#xff0c;解析数据修改翻译内容以及实现中英互译 完整代码 需求 目标网站&#xff1a;https://fanyi.so.com/# 要求&#xff1a;爬取360翻译数据包&#xff0c;实现翻译功能 所需第三方库 …...

微服务-微服务API网关Spring-clould-gateway实战

1. 需求背景 在微服务架构中&#xff0c;通常一个系统会被拆分为多个微服务&#xff0c;面对这么多微服务客户端应该如何去调用呢&#xff1f; 如果根据每个微服务的地址发起调用&#xff0c;存在如下问题&#xff1a; 1.客户端多次请求不同的微服务&#xff0c;会增加客户端…...

ECMAScript modules规范示例详解

ECMAScript modules&#xff08;简称 ES modules&#xff09;是JavaScript的标准模块系统。每个模块都是一个独立的JavaScript文件&#xff0c;可以在其中定义导出的变量、函数或类&#xff0c;并从其他模块中导入这些变量、函数或类。以下是ES modules规范的一些示例和详解&am…...

【OpenFeign常用配置】

OpenFeign常用配置 快速入门&#xff1a;1、引入依赖2、启用OpenFeign 实践1、引入依赖2、开启连接池功能3、模块划分4、日志5、重试 快速入门&#xff1a; OpenFeign是一个声明式的http客户端&#xff0c;是spring cloud在eureka公司开源的feign基础上改造而来。其作用及时基于…...

第2.1章 StarRocks表设计——概述

注&#xff1a;本篇文章阐述的是StarRocks-3.2版本的表设计相关内容。 建表是使用StarRocks非常重要的一环&#xff0c;规范化的表设计在某些场景下能使查询性能有数倍的提升。StarRocks的表设计涉及到的知识点主要包括数据表类型、数据分布&#xff08;分区分桶及排序键&#…...

WooCommerce商品采集与发布插件

如何采集商品或产品信息&#xff0c;并自动发布到Wordpress系统的WooCommerce商品&#xff1f; 推荐使用简数采集器&#xff0c;操作简单方便&#xff0c;且无缝衔接WooCommerce插件&#xff0c;快速完成商品的采集与发布。 简数采集器的智能自动生成采集规则和可视化操作功能…...

select滑动分页请求数据

需求背景 Antd 的 select 组件支滑动分页获取后端数据 实现滑动加载数据 定义变量 const allLoadedRef useRef<boolean>(true); // 是否触底 const [current, setCurrent] useState<number>(1); // 当前页 const [list, setList] useState([]); // 列表定义…...

【Go channel如何控制goroutine并发执行顺序?】

多个goroutine并发执行时&#xff0c;每一个goroutine抢到处理器的时间点不一致&#xff0c;gorouine的执行本身不能保证顺序。即代码中先写的gorouine并不能保证先执行 思路&#xff1a;使用channel进行通信通知&#xff0c;用channel去传递信息&#xff0c;从而控制并发执行…...

逆向分析Cobalt Strike安装后门

Cobalt Strike简介 Cobalt Strike是一款基于java的渗透测试神器&#xff0c;也是红队研究人员的主要武器之一&#xff0c;功能非常强大&#xff0c;非常适用于团队作战&#xff0c;Cobalt Strike集成了端口转发、服务扫描&#xff0c;自动化溢出&#xff0c;多模式端口监听&am…...

【嵌入式学习】QT-Day3-Qt基础

1> 思维导图 https://lingjun.life/wiki/EmbeddedNote/20QT 2> 完善登录界面 完善对话框&#xff0c;点击登录对话框&#xff0c;如果账号和密码匹配&#xff0c;则弹出信息对话框&#xff0c;给出提示”登录成功“&#xff0c;提供一个Ok按钮&#xff0c;用户点击Ok后…...

【杭州游戏业:创业热土,政策先行】

在前面的文章中&#xff0c;我们探讨了上海、北京、广州、深圳等城市的游戏产业现状。现在&#xff0c;我们切换视角&#xff0c;来看看另一个游戏创业热土——杭州的发展情况 最近第19届亚运会在杭州举办&#xff0c;本次亚运会上&#xff0c;电子竞技首次获准列为正式比赛项…...