如何在Golang中使用sync/atomic实现原子操作_安全并发计数
发布时间 - 2026-01-05 00:00:00 点击率:次Go 中 sync/atomic 通过底层 CPU 原子指令实现无锁高性能计数,比 mutex 更轻量高效;仅支持基础类型原子操作,需取地址调用且避免与普通赋值混用。
在 Go 中,sync/atomic 是实现无锁、高性能并发计数的核心工具。它直接映射到底层 CPU 的原子指令(如 LOCK XADD),比加锁更轻量,适合高频读写计数器场景。
为什么用 atomic 而不是 mutex?
使用 sync.Mutex 保护一个整型计数器虽然安全,但每次增减都要获取/释放锁,存在调度开销和竞争排队;而 atomic 操作是单条 CPU 指令,无上下文切换,吞吐更高。尤其在多核高并发下,性能差距明显。
注意:atomic 只支持基础类型(int32, int64, uint32, uint64, uintptr, *unsafe.Pointer)及其指针操作,不能用于结构体或 map 等复合类型。
基础计数器:增减与读取
声明计数器时必须用支持原子操作的类型(推荐 int64,避免 32 位平台对齐问题),并确保变量地址对齐(全局变量或堆分配自动满足):
立即学习“go语言免费学习笔记(深入)”;
✅ 正确示例:
- 定义:
var counter int64(全局或包级变量) - 原子自增:
atomic.AddInt64(&counter, 1) - 原子读取:
atomic.LoadInt64(&counter) - 原子写入:
atomic.StoreInt64(&counter, 100) - 条件更新(CAS):
atomic.CompareAndSwapInt64(&counter, old, new),仅当当前值等于old时才设为new,返回是否成功
常见陷阱与规避方式
— 计数器必须取地址传递给 atomic 函数,传值会报编译错误;
— 不要混用 atomic 和普通赋值(如 counter = 42),这会破坏原子性;
— 避免在非对齐内存上使用(如 struct 中未导出的 int32 字段紧邻其他字段),可能导致 panic(尤其在 ARM 上);
— atomic.Value 用于安全读写任意类型(如 map[string]int),但它不提供原子增减,只做整体替换。
完整可运行示例
以下是一个启动 10 个 goroutine 并发累加 1000 次的计数器:
package main import( "fmt" "sync" "sync/atomic" "time" ) func main() { var counter int64 var wg sync.WaitGroup for i := 0; i < 10; i++ { wg.Add(1) go func() { defer wg.Done() for j := 0; j < 1000; j++ { atomic.AddInt64(&counter, 1) } }() } wg.Wait() fmt.Println("Final count:", atomic.LoadInt64(&counter)) // 输出 10000 }
若换成普通 counter++ 且无锁,结果大概率小于 10000 —— 这正是竞态的典型表现。
# go
# golang
# 工具
# ai
# 编译错误
# 无锁
# 为什么
# String
# 整型
# 全局变量
# 结构体
# int
# 指针
# 堆
# Struct
# var
# pointer
# map
# 并发
# 多核
# 会报
# 高性能
# 是一个
# 都要
# 设为
# 更高
# 它不
# 时才
# 只做
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
简单实现Android验证码
php485函数参数是什么意思_php485各参数详细说明【介绍】
如何用ChatGPT准备面试 模拟面试问答与职场话术练习教程
Android Socket接口实现即时通讯实例代码
如何快速搭建高效香港服务器网站?
Laravel怎么使用Intervention Image库处理图片上传和缩放
iOS UIView常见属性方法小结
如何用搬瓦工VPS快速搭建个人网站?
Laravel如何实现一对一模型关联?(Eloquent示例)
装修招标网站设计制作流程,装修招标流程?
如何在IIS中新建站点并配置端口与IP地址?
node.js报错:Cannot find module 'ejs'的解决办法
Win11摄像头无法使用怎么办_Win11相机隐私权限开启教程【详解】
什么是JavaScript解构赋值_解构赋值有哪些实用技巧
Laravel怎么实现API接口鉴权_Laravel Sanctum令牌生成与请求验证【教程】
如何在云虚拟主机上快速搭建个人网站?
Python面向对象测试方法_mock解析【教程】
Laravel如何使用Laravel Vite编译前端_Laravel10以上版本前端静态资源管理【教程】
Swift中循环语句中的转移语句 break 和 continue
如何登录建站主机?访问步骤全解析
Laravel如何使用Blade模板引擎?(完整语法和示例)
Laravel怎么使用artisan命令缓存配置和视图
linux写shell需要注意的问题(必看)
ChatGPT回答中断怎么办 引导AI继续输出完整内容的方法
佐糖AI抠图怎样调整抠图精度_佐糖AI精度调整与放大细化操作【攻略】
利用python获取某年中每个月的第一天和最后一天
Laravel怎么做缓存_Laravel Cache系统提升应用速度的策略与技巧
悟空识字怎么关闭自动续费_悟空识字取消会员自动扣费步骤
Laravel如何实现邮箱地址验证功能_Laravel邮件验证流程与配置
企业网站制作这些问题要关注
如何在阿里云虚拟服务器快速搭建网站?
如何用PHP工具快速搭建高效网站?
北京网站制作公司哪家好一点,北京租房网站有哪些?
网站制作价目表怎么做,珍爱网婚介费用多少?
Laravel如何配置任务调度?(Cron Job示例)
php嵌入式断网后怎么恢复_php检测网络重连并恢复硬件控制【操作】
如何选择PHP开源工具快速搭建网站?
如何快速上传建站程序避免常见错误?
如何快速查询网站的真实建站时间?
Laravel Seeder怎么填充数据_Laravel数据库填充器的使用方法与技巧
企业在线网站设计制作流程,想建设一个属于自己的企业网站,该如何去做?
Laravel怎么配置自定义表前缀_Laravel数据库迁移与Eloquent表名映射【步骤】
Laravel怎么实现微信登录_Laravel Socialite第三方登录集成
如何在宝塔面板中创建新站点?
如何在搬瓦工VPS快速搭建网站?
香港服务器租用费用高吗?如何避免常见误区?
微信小程序 五星评分(包括半颗星评分)实例代码
微信小程序 HTTPS报错整理常见问题及解决方案
Linux系统运维自动化项目教程_Ansible批量管理实战
javascript和jQuery中的AJAX技术详解【包含AJAX各种跨域技术】


(
"fmt"
"sync"
"sync/atomic"
"time"
)
func main() {
var counter int64
var wg sync.WaitGroup
for i := 0; i < 10; i++ {
wg.Add(1)
go func() {
defer wg.Done()
for j := 0; j < 1000; j++ {
atomic.AddInt64(&counter, 1)
}
}()
}
wg.Wait()
fmt.Println("Final count:", atomic.LoadInt64(&counter)) // 输出 10000
}