Golang 学习笔记:Golang 的 sync/atomic 原子操作

发布于 2022-08-28 09:48:28 字数 1761 浏览 265 评论 0

在并发操作中,原子操作是非常现实的问题,典型的就是多个 CPU 对同一个内存的值进行操作,如 i++,很可能两次 i++,这个 i 只增加了一次,sync/atomic 就是为了解决这个问题的。具体的实现在不同的操作系统的实现是不同的, Intel 的 CPU 架构机器上,主要是使用总线锁的方式实现的。 在 AMD 的 CPU 架构机器上就是使用 MESI 一致性协议的方式来保证原子操作。

Atomic 提供了对简单类型进行操作,这些类型包括 int32, int64, uint32, uint64, uintptr, unsafe.Pointer 共6个。这些函数的原子操作共有5种:增或减,比较并交换、载入、存储和交换

如,当我们不使用原子操作的时候:

package main

import (
   "strconv"
)

var num int64

func main() {
   num = 0
   ch := make(chan string)

   for i := 0; i < 10000; i++ {
      go add(ch, i)
   }

   for i := 0; i < 10000; i++ {
      <-ch
   }

   println(num)
}

func add(ch chan string, i int)  {
   num++
   ch <- ("add" + strconv.Itoa(i))
}

多次运行,最终得到的 num 值是不同的:

按照代码逻辑应该是需要为 10000 则是符合预期的,更改使用原子操作时,将 num++ 改为 atomic.AddInt64(&num, 1)

package main

import (
   "strconv"
   "sync/atomic"
)

var num int64

func main() {
   num = 0
   ch := make(chan string)

   for i := 0; i < 10000; i++ {
      go add(ch, i)
   }

   for i := 0; i < 10000; i++ {
      <-ch
   }

   println(num)
}

func add(ch chan string, i int)  {
   atomic.AddInt64(&num, 1)
   ch <- ("add" + strconv.Itoa(i))
}

这个时候是符合预期的

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

属性

暂无简介

0 文章
0 评论
25 人气
更多

推荐作者

醉城メ夜风

文章 0 评论 0

远昼

文章 0 评论 0

平生欢

文章 0 评论 0

微凉

文章 0 评论 0

Honwey

文章 0 评论 0

qq_ikhFfg

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文