不能直接用++或=更新共享计数器,因为++是非原子的读-改-写操作,多goroutine并发时会导致数据竞争和结果错误;必须使用sync/atomic(如atomic.AddInt64)或sync.Mutex保证线程安全。
++ 或 = 更新共享计数器多个 goroutine 同时对一个 int 变量执行 counter++,结果大概率小于预期值。这不是“偶尔出错”,而是根本没定义行为:++ 是读-改-写三步操作,中间可能被抢占,导致覆盖彼此的写入。Go 编译器和 CPU 都不保证其原子性,即使变量是全局或指针指向的也不行。
go run -race 会报 Data Race;不加 -race 也可能跑出随机结果sync.Mutex 能解决问题,但有锁开销;而简单计数、标志位切换等场景,sync/atomic 更轻量atomic 系列函数操作的是内存地址,所有参数类型都要求是 *T
atomic.AddInt64 和 atomic.LoadInt64 配合使用最常见计数器增减 + 读取是原子操作最典型的组合。注意:所有整数原子操作都严格区分有符号/无符号、32/64 位,不能混用类型,否则编译失败或 panic。
var counter int64
func increment() {
atomic.AddInt64(&counter, 1)
}
func get() int64 {
return atomic.LoadInt64(&counter)
}
func main() {
var wg sync.WaitGroup
for i := 0; i < 100; i++ {
wg.Add(1)
go func() {
defer wg.Done()
increment()
}()
}
wg.Wait()
fmt.Println("final:", get()) // 总是 100
}
atomic.AddInt64 返回新值(可选),atomic.LoadInt64 是唯一安全读取方式counter++ 替代 atomic.AddInt64(&counter, 1),哪怕只有一处也破坏原子性int64 原子操作要求地址 8 字节对齐,Go 运行时通常保证,但若手动构造结构体字段顺序不当,可能触发 panicatomic.CompareAndSwapInt32 实现无锁状态机当需要“仅在满足某条件时才更新”(比如初始化一次、状态从 idle 切到 running),CAS 是核心原语。它比锁更细粒度,且天然支持乐观并发控制。
const (
stateIdle = iota
stateRunning
stateDone
)
var state int32 = stateIdle
func startWork() bool {
return atomic.CompareAndSwapInt32(&state, stateIdle, stateRunning)
}
func finishWork() {
atomic.StoreInt32(&state, stateDone)
}
func getState() int32 {
return atomic.LoadInt32(&state)
}
CompareAndSwap 返回 bool:成功则返回 true,失败不修改值int32(或 uint32)配合 CAS,int64 版本在 32 位平台需要额外指令支持,性能略低if state == stateIdle { state = stateRunning } —— 这中间存在竞态窗口,CAS 才是正确抽象atomic.Pointer[T](Go 1.19+)可用于原子替换指针,但 atomic.Value 更适合存储任意类型数据(如配置快照)。二者都不支持对结构体字段做部分更新 —— 原子操作只能针对整个值。
ato
mic.Pointer[*MyStruct] 可以安全地替换整个指针,但无法原子修改 p.Load().Field = x
atomic.Value 的 Store/Load 是类型安全的,但内部用反射,有轻微开销;适合不频繁写、高频读的场景(如全局配置)atomic.UpdateString 或 atomic.AddFloat64 —— 浮点数和字符串需靠 Value 或自定义 CAS 循环实现真正容易被忽略的是:原子操作只保证单个操作的线性化,不构成内存屏障之外的同步语义。如果后续逻辑依赖该原子操作的结果(比如写完 flag 再发消息),往往还需搭配 sync/atomic 提供的 Store/Load 内存序控制,或直接使用 chan / sync.WaitGroup 显式协调。
# go
# golang
# 字节
# ai
# 无锁
# 为什么
# 有锁
# if
# 字符串
# 结构体
# bool
# int
# 循环
# 指针
# 线程
# pointer
# 并发
# 的是
# 都不
# 会报
# 线性化
# 都要
# 多个
# 才是
# 这不是
# 一处
# 自定义
相关文章:
Android滚轮选择时间控件使用详解
桂林网站制作公司有哪些,桂林马拉松怎么报名?
建站之星IIS配置教程:代码生成技巧与站点搭建指南
c# 在ASP.NET Core中管理和取消后台任务
如何制作公司的网站链接,公司想做一个网站,一般需要花多少钱?
免费制作统计图的网站有哪些,如何看待现如今年轻人买房难的情况?
C#如何序列化对象为XML XmlSerializer用法
专业制作网站的公司哪家好,建立一个公司网站的费用.有哪些部分,分别要多少钱?
教学论文网站制作软件有哪些,写论文用什么软件
?
h5网站制作工具有哪些,h5页面制作工具有哪些?
,柠檬视频怎样兑换vip?
家族网站制作贴纸教程视频,用豆子做粘帖画怎么制作?
测试制作网站有哪些,测试性取向的权威测试或者网站?
在线制作视频网站免费,都有哪些好的动漫网站?
建站之星导航菜单设置与功能模块配置全攻略
如何通过西部建站助手安装IIS服务器?
如何通过.red域名打造高辨识度品牌网站?
小说建站VPS选用指南:性能对比、配置优化与建站方案解析
建站之星备案是否影响网站上线时间?
网站制作费用多少钱,一个网站的运营,需要哪些费用?
如何在橙子建站上传落地页?操作指南详解
,怎么在广州志愿者网站注册?
如何通过商城自助建站源码实现零基础高效建站?
建站之星安装需要哪些步骤及注意事项?
常州自助建站:操作简便模板丰富,企业个人快速搭建网站
公司网站设计制作厂家,怎么创建自己的一个网站?
Android使用GridView实现日历的简单功能
如何在香港免费服务器上快速搭建网站?
盐城做公司网站,江苏电子版退休证办理流程?
网站制作的步骤包括,正确网址格式怎么写?
如何在IIS7中新建站点?详细步骤解析
沈阳制作网站公司排名,沈阳装饰协会官方网站?
,巨量百应是干嘛的?
建站主机与服务器功能差异如何区分?
寿县云建站:智能SEO优化与多行业模板快速上线指南
如何配置WinSCP新建站点的密钥验证步骤?
三星网站视频制作教程下载,三星w23网页如何全屏?
如何在橙子建站中快速调整背景颜色?
全景视频制作网站有哪些,全景图怎么做成网页?
c++23 std::expected怎么用 c++优雅处理函数错误返回【详解】
无锡制作网站公司有哪些,无锡优八网络科技有限公司介绍?
建站之星24小时客服电话如何获取?
微网站制作教程,不会写代码,不会编程,怎么样建自己的网站?
建站之星如何实现PC+手机+微信网站五合一建站?
定制建站方案优化指南:企业官网开发与建站费用解析
招商网站制作流程,网站招商广告语?
简历在线制作网站免费,免费下载个人简历的网站是哪些?
建站之星如何保障用户数据免受黑客入侵?
如何在VPS电脑上快速搭建网站?
图片制作网站免费软件,有没有免费的网站或软件可以将图片批量转为A4大小的pdf?
*请认真填写需求信息,我们会在24小时内与您取得联系。