编程笔记 Golang基础 038 并发与原子变量

编程笔记 Golang基础 038 并发与原子变量

  • 一、原子操作(Atomic Operation)
  • 二、原子变量
  • 三、应用示例

在 Go 语言(Golang)的并发编程中,原子变量是用于确保多线程安全的重要工具。当多个 Goroutine 并发访问和修改同一变量时,如果不采取同步措施,可能会导致数据竞争(data race),即不同的 Goroutine 可能会看到变量的中间状态,从而引发难以预测的行为。

一、原子操作(Atomic Operation)

原子操作(Atomic Operation)是指在计算机系统中,尤其是在多线程或并发环境下,能够确保从开始到结束不被其他操作打断的操作序列。这种操作具有不可分割性,要么全部执行成功,要么完全不执行,不会存在执行到一半的情况。

在单核CPU的环境中,某些简单的指令如读取、写入一个字节或整数通常可以保证是原子的,因为硬件设计上一条指令执行过程不会被打断。而在多核或多处理器系统中,为了实现原子操作,处理器和内存子系统可能需要使用特殊的硬件机制,例如总线锁定、缓存一致性协议(如MESI协议)或者专门的原子指令来保证多个处理器对同一内存地址进行访问时的完整性。

原子操作在编程中的一个重要应用是避免数据竞争(Data Race),确保并发环境下的程序正确性。通过使用原子操作,开发者可以在不引入锁等同步机制的情况下安全地修改共享变量,从而提升性能并简化代码逻辑。例如,在C++11及更新版本、Go语言以及其他支持原子操作的语言和库中,都提供了相应的API来支持开发人员进行原子级别的数据操作。

二、原子变量

在 Go 语言(Golang)的并发编程中,原子变量是用于确保多线程安全的重要工具。当多个 Goroutine 并发访问和修改同一变量时,如果不采取同步措施,可能会导致数据竞争(data race),即不同的 Goroutine 可能会看到变量的中间状态,从而引发难以预测的行为。

Go 标准库中的 sync/atomic 包提供了对几种整数类型(int32、int64、uint32、uint64、uintptr 和某些指针类型)以及部分布尔类型进行原子操作的支持。这些原子操作包括:

  1. 读取(Load):以原子方式从内存地址加载值。

    • 示例:value := atomic.LoadInt32(&sharedVar)
  2. 存储(Store):以原子方式将新值存储到内存地址。

    • 示例:atomic.StoreInt32(&sharedVar, newValue)
  3. 交换(Swap):以原子方式将新值与旧值进行交换并返回旧值。

    • 示例:oldValue := atomic.SwapInt32(&sharedVar, newValue)
  4. 比较并交换(CompareAndSwap):如果当前值等于期望值,则用新值替换它,并返回替换前的值。这可以实现无锁条件更新。

    • 示例:swapped := atomic.CompareAndSwapInt32(&sharedVar, oldValue, newValue)
  5. 原子增加或减少(Add、Sub):对整数值进行原子加减操作。

    • 示例:newValue := atomic.AddInt32(&counter, 1)newValue := atomic.AddUintptr(&pointerOffset, uintptr(delta))
  6. 逻辑非操作(Toggle):仅对布尔型变量进行原子化的翻转操作。

    • 示例:newBool := atomic.CompareAndSwapBool(&flag, oldBool, !oldBool)

通过使用这些原子操作,开发人员可以在不使用锁的情况下处理简单的并发控制场景,提高程序的性能和可读性。但需要注意的是,虽然原子操作能够解决一些简单情况下的并发问题,对于更复杂的共享数据结构,可能仍需要借助互斥锁(mutexes)、读写锁(rwlocks)或其他同步原语来保证正确性。

三、应用示例

在Go语言中,原子变量的典型应用场景是实现并发安全的计数器、标志位或者其他需要多线程同步访问的数据结构。以下是一个使用 sync/atomic 包中的原子操作实现并发安全整数计数器的综合示例:

package mainimport ("fmt""sync/atomic""time"
)// 定义一个全局的int32类型的原子变量作为计数器
var counter int32 = 0func main() {// 创建10个goroutine来并发增加计数器for i := 0; i < 10; i++ {go func() {for j := 0; j < 1000; j++ {// 使用原子Add函数增加计数器的值atomic.AddInt32(&counter, 1)}}()}// 等待所有goroutine完成任务time.Sleep(time.Second)// 最终打印计数器的结果,由于使用了原子操作,结果应为10 * 1000fmt.Println("Final Counter Value:", atomic.LoadInt32(&counter))
}

在这个示例中,我们创建了一个共享的int32类型的原子变量counter。多个goroutine并发地对这个变量进行加一操作。由于每次加一是通过atomic.AddInt32函数完成的,因此即使在没有互斥锁的情况下也能确保计数的准确性,避免了数据竞争。

实际项目中,原子变量还可以用于诸如实现引用计数、状态机转换、信号量控制等场景。

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

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

相关文章

【HMAC-SHA1算法以及工作原理】

曾梦想执剑走天涯&#xff0c;我是程序猿【AK】 目录 简述概要知识图谱总结 简述概要 连接HMAC-SHA1工作原理以及工具代码 知识图谱 HMAC&#xff08;Hash-based Message Authentication Code&#xff0c;基于散列的消息认证码&#xff09;是一种结合了密钥和消息的认证方法…

刚拿到的《HarmonyOS应用开发者高级认证》,全网整理的题目,将近300题,100%通过

刚拿到《HarmonyOS应用开发者高级认证》&#xff0c;现在把题目和答案分享一下&#xff0c;这些题目是我根据其他网站整理的&#xff0c;宁滥勿缺&#xff0c;有个别题目是重复的&#xff0c;抽半天时间看一下&#xff0c;应该是稳过的。当然建议还是先跟着文档学一下鸿蒙或者看…

Centos 7.5 上nginx设置开机自启动

nginx的安装目录 &#xff1a; /usr/local/nginx 一、没有设置开机自启动前&#xff0c;需要执行/usr/local/nginx/sbin/nginx 启动 二、接下来&#xff0c;我们设置开机自启动&#xff0c;就不用手动启动nginx了 1、cd /usr/lib/systemd/system/ 2、vi nginx.service [un…

如何在Win系统搭建Oracle数据库并实现远程访问【内网穿透】

文章目录 前言1. 数据库搭建2. 内网穿透2.1 安装cpolar内网穿透2.2 创建隧道映射 3. 公网远程访问4. 配置固定TCP端口地址4.1 保留一个固定的公网TCP端口地址4.2 配置固定公网TCP端口地址4.3 测试使用固定TCP端口地址远程Oracle 前言 Oracle&#xff0c;是甲骨文公司的一款关系…

TensorRT及CUDA自学笔记007 运行时库及矩阵加法demo

TensorRT及CUDA自学笔记007 运行时库及矩阵加法demo Runtime 运行时库 明天再补充&#xff0c;先去准备面试了 矩阵加法demo cudaMalloc和cudaMemcpy 它们和c的malloc和memcpy功能一致&#xff0c;只是操作的不是host端的内存空间&#xff0c;而是device端的”显存空间“ …

【深入理解设计模式】适配器设计模式

适配器设计模式 适配器设计模式是一种结构型设计模式&#xff0c;用于将一个类的接口转换成客户端所期望的另一个接口&#xff0c;从而使得原本由于接口不兼容而不能一起工作的类能够一起工作。适配器模式通常用于以下场景&#xff1a; 现有接口与需求不匹配&#xff1a;当需要…

Linux安装Mysql(超详细,亲测)

文章中的全部内容自己都有亲身实践&#xff0c;都是有效的&#xff0c;像常见登录错误中&#xff0c;那种错误的密码修改方式自己以前就浪费了很多事件&#xff0c;还有设置Mysql远程登录这些也是&#xff0c;所以我把这些操作整理了一下&#xff0c;让大家在安装和使用Mysql的…

YOLOv6代码解读[02] configs/hub/yolov6l_finetune.py文件解读

文章目录 模型配置文件骨干网络 CSPBepBackbone颈部网络 CSPRepBiFPNNeck检测头 EffiDeHead构建模型Model 模型配置文件 # YOLOv6l model model dict(typeYOLOv6l,pretrainedweights/yolov6l.pt,depth_multiple1.0,width_multiple1.0,backbonedict(typeCSPBepBackbone,num_re…

多线程基础说明【基础篇】

目录 &#x1f32d;1.相关概念 &#x1f37f;2.创建和启动线程 &#x1f95e;3.线程安全 &#x1f9c8;4.死锁 &#x1f953;5.线程通信的方法 1.相关概念 1.1程序 为完成特定任务&#xff0c;用某种语言编写的一组指令的集合。即指一段静态的代码&#xff0c;静态对象…

都2024年了,软件测试面试都问什么?

1、最熟悉的 selenium 操作&#xff1f; 基本上 selenium 提供的一下几大类操作都能够灵活使用&#xff0c;比如说&#xff1a;八大元素定位方式、三大等待方式、用户点击、输入等常见操作、 还有窗口切换、iframe 切换操作&#xff0c;比如说 actionchains 文件上传、JS操作 等…

网站开发--详解Servlet

&#x1f495;"Echo"&#x1f495; 作者&#xff1a;Mylvzi 文章主要内容&#xff1a;网站开发–详解Servlet 一.基本介绍 tomcat是Java中开发服务器的重要的一个工具,任何开发的服务器都要部署在tomcat之上,可以说tomcat是所有服务器的底座,为了更好的操作http,to…

Pom文件中的scope到是什么作用

在 Maven 的 pom.xml 文件中&#xff0c;<scope> 标签用于定义依赖项的作用域。作用域决定了依赖项的生命周期、可见性和使用范围。<scope> 标签的常用值包括&#xff1a; 1. **compile**&#xff08;默认值&#xff09;&#xff1a;编译依赖在所有 classpath 中都…

golang学习3,golang 项目中配置gin的web框架

1.go 初始化 mod文件 go mod init gin-ranking 2.gin的crm框架 go get -u github.com/gin-gonic/gin 3.go.mod爆红解决

【Redis】redis通用命令

redis连接命令 要在 redis 服务上执行命令需要一个 redis 客户端。Redis 客户端在我们之前安装redis 的src目录下&#xff0c;具体为/usr/local/redis/src。注意此redis实例没有设置密码&#xff0c;如果设置了密码需要先使用命令AUTH执行验证或者开始在命令行中通过-a指定。 …

前后端分离Vue+node.js在线学习考试系统gqw7o

与其它应用程序相比&#xff0c;在线学习平台的设计主要面向于学校&#xff0c;旨在为管理员和学生、教师、院系提供一个在线学习平台。学生、教师、院系可以通过系统及时查看公告信息等。 在线学习平台是在Windows操作系统下的应用平台。为防止出现兼容性及稳定性问题&#xf…

B站项目-基于Pytorch的ResNet垃圾图片分类

基于Pytorch的ResNet垃圾图片分类 数据集预处理 画图片的宽高分布散点图 import osimport matplotlib.pyplot as plt import PIL.Image as Imagedef plot_resolution(dataset_root_path):image_size_list []#存放图片尺寸for root, dirs, files in os.walk(dataset_root_pa…

装配制造业的MES系统种的物料齐套技术

装配是制造企业涉及产品生产加工最为普遍的一种模式&#xff0c;包括汽车、电子、电器、电气等行业。经研究表明&#xff0c;装配在整个产品制造总成本中所占比例超过了50%&#xff0c;所占用的总生产时间比例在40%-60%&#xff0c;直接影响着产品质量和成本。装配制造非常强调…

树-王道-复试

树 1.度&#xff1a; 树中孩子节点个数&#xff0c;所有结点的度最大值为 树的度 2.有序树&#xff1a; 逻辑上看&#xff0c;树中结点的各子树从左至右是有次序的&#xff0c;不能互换。 **3.**树的根节点没有前驱&#xff0c;其他节点只有一个前驱 **4.**所有节点可有零个或…

Leetcoder Day23| 回溯part03:组合+分割

语言&#xff1a;Java/Go 39. 组合总和 给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target &#xff0c;找出 candidates 中可以使数字和为目标数 target 的所有不同组合 &#xff0c;并以列表形式返回。你可以按任意顺序返回这些组合。 candidates 中的同一个…

机器学习是什么

机器学习是什么 引言 机器学习&#xff08;Machine Learning&#xff0c;简称ML&#xff09;是人工智能&#xff08;AI&#xff09;领域中的重要分支&#xff0c;旨在通过让计算机系统自动学习和适应&#xff0c;不需要明确的编程指导。机器学习的发展为我们提供了一种新的方…