atomic.AddInt32锁和sync.Mutex锁的区别

news/2025/3/26 18:29:16/文章来源:https://www.cnblogs.com/maidongdong/p/18790258

是的,你说得没错,atomic.AddInt32 在底层确实涉及一种“锁”的机制,但它和我们通常理解的软件层面的加锁(如 sync.Mutex)有所不同。让我们澄清一下这两种“锁”的区别,以及为什么原子操作的“锁”更高效。

原子操作中的“锁”

atomic.AddInt32 中,所谓的“锁”是指硬件层面通过 CPU 指令实现的内存总线锁定(例如 x86 的 LOCK 前缀)。这种锁定有以下特点:

  1. 范围极小:它只锁定特定的内存地址(例如变量 i 所在的内存单元),而不是整个程序或资源。
  2. 时间极短:锁定仅在执行单一原子指令(如 LOCK XADD)期间有效,通常只持续几个 CPU 时钟周期。
  3. 硬件实现:由 CPU 直接控制,通过内存总线协议(如 MESI 缓存一致性协议)确保其他核心无法同时访问同一内存地址。

这种“锁”不需要操作系统介入,也不需要线程切换,因此开销非常低。它本质上是硬件级别的同步机制,而不是软件层面的锁。

对比 sync.Mutex

sync.Mutex 是 Go 标准库提供的互斥锁,属于软件层面的锁,其特点包括:

  1. 范围较大:锁保护的是代码块(临界区),可以包含多条指令,不限于单一操作。
  2. 时间较长:锁的持有时间取决于临界区代码的执行时间,可能涉及复杂的逻辑。
  3. 软件实现:由 Go 的运行时管理,可能涉及用户态和内核态的切换(例如当锁被争抢时,线程会被挂起)。
  4. 开销较高:涉及调度、上下文切换等操作,尤其在高竞争场景下性能下降明显。

例如:

mu.Lock()
i = i + 1
mu.Unlock()

这里的 mu.Lock()mu.Unlock() 保护了一个完整的代码块,可能包含多步操作。

为什么原子操作的“锁”不完全等同于加锁?

尽管 atomic.AddInt32 用到了硬件的 LOCK 机制,但它和 sync.Mutex 的“加锁”在概念和使用上有显著区别:

  • 粒度:原子操作的“锁”是针对单一内存操作的最小粒度,而 sync.Mutex 是针对代码块的粗粒度。
  • 功能:原子操作只能完成简单的计算(如加减、比较并交换),而 sync.Mutex 可以保护任意复杂的逻辑。
  • 开销:硬件锁的开销远低于软件锁,因为它避免了线程调度和上下文切换。

一个形象的比喻

  • 原子操作(atomic.AddInt32:就像在银行柜台前快速按一下计数器,机器自动加 1,过程中没有人能插队,整个动作一气呵成。
  • 互斥锁(sync.Mutex:像是锁住整个柜台,只有你一个人能进去,办完所有业务(可能不止加 1)后再出来,期间其他人只能排队等候。

验证“锁”的存在

在某些架构下,原子操作的实现确实依赖锁。例如:

  • x86 的 LOCK 前缀明确锁住内存总线。
  • ARM 架构可能使用 LDREXSTREX(独占加载和存储)来实现类似效果,间接达成原子性。

但在一些情况下,现代 CPU 可能会优化原子操作,使用无锁(lock-free)技术(例如基于缓存一致性协议),不过这对用户来说是透明的,效果仍然是原子性的。

结论

是的,atomic.AddInt32 在底层确实涉及“锁”,但它是硬件级别的、轻量级的内存总线锁定,与 sync.Mutex 的软件加锁机制在实现和应用场景上完全不同。正是因为这种硬件支持,原子操作才能在并发中高效地保证递增的原子性,而无需付出传统加锁的高昂代价。

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

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

相关文章

React Native开发鸿蒙Next---富文本浏览

React Native开发鸿蒙Next---富文本浏览 最近在继续开发App剩余的社区功能。地铁的社区相对较为特殊,只有公告/政策规章/操作指南等资讯阅读功能,无法进行交互。对于原先的社区RN,除了移植适配鸿蒙,还需要做大量的功能屏蔽等改造。新的社区后台大量采用富文本进行内容编辑,…

17.指针

正如您所知道的,每一个变量都有一个内存位置,每一个内存位置都定义了可使用 & 运算符访问的地址,它表示了在内存中的一个地址。 请看下面的实例,它将输出定义的变量地址:#include <stdio.h>int main(){int var_runoob = 10;int *p; //定义指针变量p = &var…

3.24 学习记录

实现了学习记录APP的登录注册功能

2025西安交大集训Day2:DFS,BFS记忆化搜索,迭代加深搜索,二分搜索

2025西安交大集训Day2:DFS,BFS记忆化搜索,迭代加深搜索,二分搜索

掌握 Postman:高级 GET 请求技术与响应分析

欢迎阅读本指南,它将详细介绍如何在 Postman 中发送 GET 请求并理解 API 响应。对于希望提升 API 测试和开发能力的开发者来说,这是不可或缺的技能。 Postman 对开发者的重要性Postman 是 API 开发和测试中不可或缺的工具。它不仅简化了发送请求和分析响应的过程,还提供了一…

带你一起来熟悉linux文件权限体系

了解 Linux 文件权限对于有效且可靠的linux相关系统管理和安全管理至关重要。通过本文中概述的概念并加以实践,您将可以轻松浏览文件权限并确保 Linux 系统的完整,可靠和安全。下面将从权限的格式,常用设置,修改,解析等方面分别说明。 A).Linux 文件权限由三个权限部分组成…

OP100自动安装背板常见问题

1.运行过程中切手动,回原灯一直闪烁,始终无法执行完成 OP50自动安装座板 OP100自动安装背板 OP280自动安装上盖 这几个工站因为有记忆功能,会记住当前步序以及夹爪/吸盘上有没有物体,如果运行中切换手动,并动了气缸,会导致逻辑错乱,类似升降器的SUB40,遇到这种情况: 1…

20244217 2024-2025-2 《Python程序设计》实验一报告

学号 2024-2025-2 《Python程序设计》实验一报告 课程:《Python程序设计》 班级: 2442 姓名: 胡峻豪 学号:20244217 实验教师:王志强 实验日期:2025年3月24日 必修/选修: 公选课 1.实验内容 1.熟悉Python开发环境。首先在官网下载并安装PyCharm专业版,安装完成后打开软…

软件工程日报15

Android studio 实现连接远程mysql数据库,并将数据展示出来,由于之前没接触过,全靠按照博客上的指导和ai生成的代码,之后在学习一下 以下是效果

《Python程序设计》实验一报告

课程:《Python程序设计》 班级: 2441 姓名: 王晓凤 学号:20244127 实验教师:王志强 实验日期:2025年3月24日 必修/选修: 公选课 一.实验内容 1.熟悉Python开发环境:本次实验使用了PyCharm。首先在官网下载并安装PyCharm社区版,安装完成后打开软件,创建一个新的Pytho…

抽象bug:mybatis-xml配置错误(configuration and configLocation can not specified with together)

mybatis-xml配置错误(configuration and configLocation can not specified with together) 操作 我在使用mybatis-XML映射配置时,没有将mappper的xml文件放在同名同包的路径下,而是使用辅助配置,在配置文件中设置XML路径.然而,在配置文件后,没有成功,一直报错. 错误信息:"…