Golang 中 sync/atomic 包的原子操作

news2025/7/20 9:41:07

背景

Go中多协程的情况下, 要保证操作的原子性,一般要使用RWMutex或者Mutex, 但是锁使用起来比较复杂,还要考虑lock 和unlock 顺序和成对出现,不注意就容易出错。
于是在sync/atomic包中,把我们常用的一些操作封装成原子操作,提供了更加轻量级的解决方案

Add 方法

简介

提供了将两个操作数相加的方法, 共有以下方法

func AddInt32(addr *int32, delta int32) (new int32)
func AddUint32(addr *uint32, delta uint32) (new uint32)
func AddInt64(addr *int64, delta int64) (new int64)
func AddUint64(addr *uint64, delta uint64) (new uint64)
func AddUintptr(addr *uintptr, delta uintptr) (new uintptr

这里的 AddUint32, AddUint64, AddUintptr 的参数是无符号类型, 标识可以使用 - 来进行减法操作

示例

package main

import (
	"fmt"
	"sync/atomic"
	"time"
)
func main() {
	// 加法案例
	var count int32
	for i:= 0;i < 100 ; i++{
		go func() { atomic.AddInt32(&count,1) }()
	}
	// 等待协程执行完
	time.Sleep(5*time.Second)
	fmt.Println("ADD count:", count)
	// 减法案例
	var sub_param1  uint32 = 100
	var sub_param2  uint32 = 1
	for i:= 0;i < 100 ; i++{
			// 添加了 - , 表示减法, 只能作用于无符号类型变量
		go func() { atomic.AddUint32(&sub_param1,-sub_param2)}()
	}
	// 等待协程执行完
	time.Sleep(5*time.Second)
	fmt.Println("SUB sub_param1:", sub_param1)
}

执行结果:
在这里插入图片描述
可以看到, 使用atomic操作更加简洁和方便.

其他方法

类似于Add, atomic 也提供了其他原子操作方法

Swap 方法,Swap 方法的功能是原值替换为新值,并返回原值。

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)

CompareAndSwap 方法,功能是比较 addrold, 相等将addr的值替换为new, 返回值是是否进行了替换.

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)

Load 方法是简单的提取操作

func LoadInt32(addr *int32) (val int32)
func LoadInt64(addr *int64) (val int64)
func LoadUint32(addr *uint32) (val uint32)
func LoadUint64(addr *uint64) (val uint64)
func LoadUintptr(addr *uintptr) (val uintptr)
func LoadPointer(addr *unsafe.Pointer) (val unsafe.Pointer)

Store 方式是写入操作, 将val写入 addr

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)

还有一个属于Value类型的方法, 可以存取任何类型的数据, 相当于一个数据存取空间, 但是同一个 Value 类型的实例,只能存取一种类型的数据, 只要调用过一次 Store 方法,那么传入此方法的后续参数类型必须和之前传入参数的类型一致,否则会导致 panic

func (v *Value) Load() (x interface{})
func (v *Value) Store(x interface{})

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/395426.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【源码库】跟着 Vue3 学习前端模块化

Vue3为了支持不同的用户群体&#xff0c;提供了多种模块化方案&#xff0c;这样使得我们在使用的Vue的使用可以有很多种方式&#xff1b; 例如我们可以直接在html中使用script标签引入Vue&#xff0c;也可以前端工程化工具&#xff0c;例如webpack、rollup等打包工具&#xff…

2023年湖北一级技师二级技师报名时间、考试时间是什么时候?

2023年湖北一级技师二级技师报名时间、考试时间是什么时候&#xff1f; 技师是属于职业资格证书&#xff0c;是各行业的高级技术人员中设置的技术职务。技师是技能高超的技术人员、能工巧匠&#xff0c;具有丰富的实践经验&#xff0c;能在本工种难度较大的工艺加工、复杂设备、…

数据治理之数据梳理

目录 1.定义 2.用途作用 3.实施方法 3.1自上而下 3.1.1数据域梳理 3.1.2数据主题梳理 3.1.3 数据实体梳理 3.1.4设计数据模型 3.1.5优点 3.1.5缺点 3.2自下而上 3.2.1需求分析 3.2.2展现 3.2.3分析逻辑 3.2.4数据建模 3.2.5优点 3.2.6缺点 1.定义 “数据梳理”即对…

C语言例程:用二维数组实现矩阵转置

用二维数组实现矩阵转置 本实例将输入的 34 矩阵转置为 43 矩阵&#xff0c;并输出结果。通过本实例&#xff0c;可以学习如何使用二 维数组。 实例解析 二维数组的定义 二维数组定义的一般形式为&#xff1a; 第一部分 基础篇 X2277 类型说明符 数组名[常量表达式][常量表…

STM32移植FreeRTOS操作系统

一、FreeRTOS源码下载&#xff08;1&#xff09;移植钱得准备前菜对吧&#xff0c;我们先来去官网瞄一瞄网址&#xff1a;https://freertos.org/zh-cn-cmn-s/ 第一步&#xff1a;点击下载FreeRTOS第二步&#xff1a;选择版本下载&#xff08;我选择稳定版本&#xff09;注&…

git 双因子身份登录遇到的问题及解决方法

git 双因子身份登录描述&#xff1a; 一般我们登录账号和密码的时候都是通过git的账号和密码直接登录即可&#xff0c;但是如果我们用双因子身份进行登录的时候发现用账号和密码登录一直登录不了&#xff0c;&#xff0c;&#xff0c;&#xff0c;有点emo了。。 git 双因子身份…

CentOS8基础篇13:yum与dnf软件包管理器

一、YUM工具的使用 yum可以说是一个管理rpm软件包的前端工具&#xff0c;其基于rpm软件包进行管理&#xff0c;能够从指定服务器自动下载rpm软件包并进行安装&#xff0c;可以自动处理依赖关系&#xff0c;并一次安装所有需要的软件包。在RHEL本地操作系统中设置相应的软件仓库…

SAP smartforms打印图片

注意&#xff1a;SAP只能上传打印bmp格式图片 1.标准程序上传 T-CODE:SE78 2.程序代码上传 DATA: P_FILENAME TYPE RLGRAP-FILENAME,P_NAME TYPE STXBITMAPS-TDNAME,P_TITLE LIKE BAPISIGNAT-PROP_VALUE,P_DOCID TYPE STXBITMAPS-DOCID,P_RESOLUTION TYPE …

案例分析之——理由Mybatis动态SQL实现复用

无复用思想的做法&#xff1a; 在没有复用思想的时候&#xff0c;就只顾着实现功能。比如开发过程中涉及到两个表的更新功能&#xff0c;每需要更新一处&#xff0c;就写一个接口&#xff0c;结果出现了写了11个接口的情况。 这样虽然功能实现了&#xff0c;可是可能自…

express+websocket实现线上聊天

1.webSocket简介 WebSocket是一种通信协议&#xff0c;可在单个TCP连接上进行全双工通信。WebSocket使得客户端和服务器之间的数据交换变得更加简单&#xff0c;允许服务端主动向客户端推送数据。在WebSocket API中&#xff0c;浏览器和服务器只需要完成一次握手&#xff0c;两…

SpringCloud之 Hystrix服务熔断

文章目录一、Hystrix 服务熔断 (已过时)&#x1f349;1.1 服务降级&#x1f349;1.2 服务熔断&#x1f349;1.3 OpenFeign 实现降级二、hystrix-dashboard 监控&#x1f34b;2.1 监控页面部署&#x1f34b;2.2 观察现象提示&#xff1a;以下是本篇文章正文内容&#xff0c;Spri…

【PySide6】信号(signal)和槽函数(slot),以及事件过滤器

说明 在PYQT中&#xff0c;父控件可以通过两种方式响应子控件的事件&#xff1a; 通过信号(signal)和槽函数(slot)机制连接子控件和父控件父控件可以通过设置eventFilter()方法来监听响应子控件的事件 一、信号(signal)和槽函数(slot) 示例 在PYQT中&#xff0c;每个组件都…

传输线的物理基础(三):传输线的瞬时阻抗

每个信号都有一个上升时间 RT&#xff0c;通常是从 10% 到 90% 的电压电平测量的。当信号沿传输线向下移动时&#xff0c;前沿在传输线上展开并具有空间范围。如果我们可以冻结时间并观察电压分布向外移动时的大小&#xff0c;我们会发现类似下图的东西。传输线上上升时间的长度…

Python中的三器一闭(详细版)

python中的三器一闭迭代器什么是迭代什么是可迭代对象判断数据是否可迭代什么是迭代器迭代器的本质使用迭代器取数据自定义迭代器生成器创建生产器的方法关键字yieldnext和send装饰器装饰器的功能定义装饰器闭包什么是闭包函数、匿名函数、闭包、对象 当做实参时的区别迭代器 …

Blazor_WASM之3:项目结构

Blazor_WASM之3&#xff1a;项目结构 Blazor WebAssembly项目模板可选两种&#xff0c;Blazor WebAssemblyAPP及Blazor WebAssemblyAPP-Empty 如果使用Blazor WebAssemblyAPP模板&#xff0c;则应用将填充以下内容&#xff1a; 一个 FetchData 组件的演示代码&#xff0c;该…

蓝桥杯-最优清零方案(2022省赛)

蓝桥杯-最优清零方案1、问题描述2、解题思路3、代码实现1、问题描述 给定一个长度为 N 的数列 1,2,⋯,A1,A2,...,ANA_1,A_2,...,A_NA1​,A2​,...,AN​ 。现在小蓝想通过若干次操作将 这个数列中每个数字清零。 每次操作小蓝可以选择以下两种之一: 1. 选择一个大于 0 的整数, 将…

杂记——18.VSCode的下载及使用

这篇文章&#xff0c;我们来讲一下VSCode&#xff0c;讲一下如何下载及使用VSCode 目录 1.VSCode的下载 1.1VSCode的简介 1.2VSCode的下载与安装 1.2.1下载 1.2.2安装 2.VSCode的使用 2.1界面 2.2基础设置 2.3禁用自动更新 2.3自动保存设置 2.4Vscode更换主题 2.5…

Hive面试题-HQL转换MapReduce底层核心逻辑剖析

视频可查看&#xff1a;https://www.bilibili.com/video/BV1RV41147Tb/?spm_id_from333.999.0.0&vd_source3ba3c3ba31427f60d734ede7a948de4a 原文地址&#xff1a;Hive学习之路 &#xff08;二十&#xff09;Hive 执行过程实例分析 - 扎心了&#xff0c;老铁 - 博客园 (c…

K_A14_012基于STM32等单片机驱动GY-25倾斜度角度模块 串口与OLED0.96双显示

K_A14_012基于STM32等单片机驱动GY-25倾斜度角度模块 串口与OLED0.96双显示一、资源说明二、基本参数参数引脚说明三、驱动说明对应程序:四、部分代码说明1、接线引脚定义1.1、STC89C52RCGY-25倾斜度角度模块1.2、STM32F103C8T6GY-25倾斜度角度模块五、基础知识学习与相关资料下…

测试按方向的分类

按方向分(都是在系统测试阶段测试的) 功能测试&#xff1a;举例说明什么是功能 性能测试 ①压力测试&#xff1a;不断地增加压力&#xff0c;从而找到系统的极限 ②负载测试&#xff1a;系统在极限工作条件下&#xff0c;最多能持续多久——可能发生内存泄漏/溢出&#xff0c;导…