深入理解 Go 语言原子内存操作

ops/2024/9/23 8:13:41/

        原子内存操作提供了实现其他同步原语所需的低级基础。一般来说,你可以用互斥体和通道替换并发算法的所有原子操作。然而,它们是有趣且有时令人困惑的结构,应该深入了解它们是如何工作的。如果你能够谨慎地使用它们,那么它们完全可以成为代码优化的好工具,而不会增加复杂性。

1. 原子内存操作的内存保证

        为什么我们需要单独的函数来进行原子内存操作?如果我们写入一个变量,其大小小于或等于机器字长( 现代计算机的机器字长一般都 8 位的整数倍,如 8 位、16 位等,这是由 int 类型定义的东西),例如 a = 1 ,这不就是原子的吗?

        Go 内存模型实际上保证了写操作是原子的,但是它并不能保证其他 goroutine 何时会看到该写操作的效果。

        让我们仔细分析这句话的含义。第一层意思是说,如果你从一个 goroutine 中写入与机器字长(即int) 大小相同的共享内存位置并从另一个 goroutine 中读取它,那么即使存在竞争,你也不会观察到写入操作之前的值或写入操作之后的值(并非所有语言都如此)。这意味着,如果写操作大于机器字长,那么读取该值的 goroutine 可能会看到底层对象处于不一致的状态。例如,string 值包括两个值:指向底层数组的指针和字符串长度。对这些单独的写入操作是原子的,但快速读取操作可能会读取带有 nil 数组但长度非零的字符串。

        这句话的第二层意思是说,编译器可能优化或重新排序代码,或者硬件可能乱序执行内存操作,从而使另一个 goroutine 在预期时间无法看到写入操作的效果。说明这一点的标准示例就是以下内存竞争:

Go">package mainfunc main() {var str stringvar done boolgo func() {str = "Done!"done = true}()for !done {}fmt.Println(str)
}

        这里就存在内存竞争,因为 str 变量和 done 变量在一个 goroutine 中被写入并在另一个 goroutine 中被读取,但没有显式同步。

该程序有多种可能的结果:

  • 它可以输出 Done ! 。
  • 它可以

http://www.ppmy.cn/ops/96842.html

相关文章

浅谈JVM

JVM(Java Virtual Machine,Java虚拟机) JVM是Java程序能够跨平台运行的关键所在。 JVM是一个虚拟的计算机,它模拟了真实计算机的各种硬件功能。其主要作用是加载.class字节码文件,并执行其中的指令。 以下是JVM的一…

linux Shell 脚本 输出日志文件 log /dev/null

linux Shell 脚本 输出日志文件 log shell 错误输出重定向到标准输出 https://www.jb51.net/article/264888.htm shell 错误输出重定向到标准输出 和<是文件重定向符。那么1和2是什么&#xff1f; shell中每个进程都和三个系统文件相关联 标准输入stdin 标准输出stdout 标…

python—— SOLID原则

SOLID 是面向对象设计中的五个核心原则&#xff0c;用于创建更易维护、可扩展和灵活的软件系统。它们分别是单一职责原则&#xff08;S&#xff09;、开放封闭原则&#xff08;O&#xff09;、里氏替换原则&#xff08;L&#xff09;、接口隔离原则&#xff08;I&#xff09;和…

深度学习基础—动量梯度下降法

1.算法原理 动量梯度下降法就是在梯度下降法的基础上&#xff0c;使用指数加权移动平均值&#xff0c;来平均梯度&#xff0c;这种算法比梯度下降法更快。 如上图&#xff0c;损失函数的最小值是红点&#xff0c;椭圆是损失函数的图像&#xff0c;梯度下降法就像蓝线和紫线&…

WebDeveloper:1靶机

信息收集&#xff1a; 靶机地址&#xff1a;https://www.vulnhub.com/entry/web-developer-1,288/ &#xff08;1&#xff09;ip扫描 nmap 192.168.254.0/24 -sn | grep -B 2 00:0C:29:0F:DB:75 &#xff08;2&#xff09;端口扫描 nmap -p- -A 192.168.254.160 &#xff0…

延迟加载JS有哪些方式

1、defer 等HTML全部解析完成&#xff0c;才会执行js代码&#xff0c;按顺序执行js脚本 <script defer typetext/javascript srcscript.js></script> 2、async async是和HTML解析同步的&#xff08;一起的&#xff09;&#xff0c;不是按顺序执行js脚本&#xff0…

【JavaEE】MyBatis 实战指南:从 JDBC 到高效数据库操作的进阶教程

目录 MyBatis 操作数据库JDBC 操作⽰例回顾什么是MyBatis?MyBatis⼊⻔1. 准备⼯作2. 配置数据库连接字符串3. 写持久层代码4. 单元测试使用MyBatis可能遇到的问题 MyBatis的基础操作打印⽇志参数传递增(Insert)返回主键 删(Delete)改(Update)查(Select)起别名结果映射开启驼峰…

派森学长带你学python—集合

python中的集合是无序不重复元素序列 集合中只能存储不可变数据类型 在Python中用{}来定义 与列表字典一样&#xff0c;集合石python中的可变数据类型 集合属于序列中的一种#集合的创建1 s{(1,2,3),hello,9} print(s)#{9, hello, (1, 2, 3)}#集合的创建2 set() sset() print(s)…