0

0

Golang初级实战:实现一个简单的线程安全计数器 Go语言Atomic应用

P粉602998670

P粉602998670

发布时间:2026-03-12 02:07:23

|

623人浏览过

|

来源于php中文网

原创

不能直接用int当计数器,因非原子操作会导致竞态——counter++在汇编层为读-改-写三步,多goroutine并发时结果必然不可靠;必须用sync.mutex或sync/atomic,后者要求显式使用uint64等对齐类型并配对load/store/add操作。

golang初级实战:实现一个简单的线程安全计数器 go语言atomic应用

为什么不能直接用 int 当计数器

多个 goroutine 同时读写一个 int 变量,不加同步会出错——不是“偶尔错”,而是“必然不可靠”。Go 的内存模型不保证非原子操作的可见性和顺序性,哪怕只是 counter++ 这种看似简单的语句,在汇编层也是“读-改-写”三步,中间可能被其他 goroutine 插入修改,结果丢失。典型现象是:启 10 个 goroutine 各自加 1000 次,最后 counter 值远小于 10000,且每次运行结果还不一样。

常见错误写法:

var counter int<br>go func() { counter++ }()

这完全没做同步,等同于裸奔。

解决思路只有两个:锁(sync.Mutex)或原子操作(sync/atomic)。前者通用但有锁开销;后者轻量、无锁、适合简单数值操作——这正是 sync/atomic 的定位。

Atomic.LoadUint64 和 Atomic.AddUint64 怎么配对用

Go 的 atomic 包不支持 int 类型的原子操作(避免符号扩展歧义),必须显式用带类型后缀的函数,最常用的是 uint64。别试图用 int64 的版本去存负数计数器——虽然能编译,但一旦涉及位运算(比如 LoadInt64 底层仍按补码解释),在跨平台或和 C 交互时容易翻车。

正确配对方式:

  • 初始化用 var counter uint64(不是 int
  • 读取用 atomic.LoadUint64(&counter)(不能直接读变量)
  • 累加用 atomic.AddUint64(&counter, 1)(传地址,第二个参数是 uint64
  • 重置用 atomic.StoreUint64(&counter, 0)

示例片段:

var hits uint64<br>go func() { atomic.AddUint64(&hits, 1) }()<br>fmt.Println(atomic.LoadUint64(&hits)) // 安全读

为什么 Atomic 不适用于复杂状态更新

sync/atomic 只管单个值的原子读写或简单算术,没法保证“读 A → 改 B → 写 C”这种多步逻辑的原子性。比如想实现“只在计数器为偶数时才加 1”,用 if atomic.LoadUint64(&c)%2 == 0 { atomic.AddUint64(&c, 1) } 是错的——两次原子调用之间,c 可能已被别的 goroutine 改过,条件失效。

立即学习go语言免费学习笔记(深入)”;

VIVA
VIVA

一个免费的AI创意视觉设计平台

下载

这时候必须换方案:

  • atomic.CompareAndSwapUint64 手动实现 CAS 循环(适合简单条件)
  • 或者直接上 sync.Mutex,代码更直白,性能差异在绝大多数场景下可忽略

别为了“看起来无锁”硬套 atomic——它不是万能补丁,只是工具箱里一把小螺丝刀。

在 struct 里嵌入 atomic 字段要注意什么

如果把 uint64 字段塞进 struct,又想原子操作,得确保它在内存中没有被编译器“挤在一起”导致误读。Go 要求原子变量必须是 64 位对齐的,而 struct 成员顺序和 padding 由编译器决定。

安全做法:

  • 把原子字段声明在 struct 第一个位置(最保险)
  • 或者用 align64 标签(Go 1.21+)显式对齐:count uint64 `align64`
  • 绝对不要用 unsafe.Offsetof 算偏移再手动操作——破坏类型安全,且 Go 版本升级可能让布局变化

错误示范:

type Counter struct {<br>  name string<br>  count uint64 // 可能不对齐!<br>}

这样 atomic.LoadUint64(&c.count) 在某些平台会 panic “unaligned 64-bit atomic operation”。

真正麻烦的从来不是“怎么写对”,而是“什么时候不该用”。Atomic 看似简单,但类型选择、内存对齐、复合逻辑边界,哪一环松动都会让并发行为滑向不可预测。写完记得跑 go run -race,别信感觉。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
golang如何定义变量
golang如何定义变量

golang定义变量的方法:1、声明变量并赋予初始值“var age int =值”;2、声明变量但不赋初始值“var age int”;3、使用短变量声明“age :=值”等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

210

2024.02.23

golang有哪些数据转换方法
golang有哪些数据转换方法

golang数据转换方法:1、类型转换操作符;2、类型断言;3、字符串和数字之间的转换;4、JSON序列化和反序列化;5、使用标准库进行数据转换;6、使用第三方库进行数据转换;7、自定义数据转换函数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

247

2024.02.23

golang常用库有哪些
golang常用库有哪些

golang常用库有:1、标准库;2、字符串处理库;3、网络库;4、加密库;5、压缩库;6、xml和json解析库;7、日期和时间库;8、数据库操作库;9、文件操作库;10、图像处理库。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

356

2024.02.23

golang和python的区别是什么
golang和python的区别是什么

golang和python的区别是:1、golang是一种编译型语言,而python是一种解释型语言;2、golang天生支持并发编程,而python对并发与并行的支持相对较弱等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

214

2024.03.05

golang是免费的吗
golang是免费的吗

golang是免费的。golang是google开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的开源编程语言,采用bsd开源协议。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

409

2024.05.21

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

490

2025.06.09

golang相关判断方法
golang相关判断方法

本专题整合了golang相关判断方法,想了解更详细的相关内容,请阅读下面的文章。

201

2025.06.10

golang数组使用方法
golang数组使用方法

本专题整合了golang数组用法,想了解更多的相关内容,请阅读专题下面的文章。

1438

2025.06.17

C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

3

2026.03.11

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Go 教程
Go 教程

共32课时 | 6.1万人学习

Go语言实战之 GraphQL
Go语言实战之 GraphQL

共10课时 | 0.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号