0

0

Go初级项目如何处理并发安全_Go锁与并发实战

P粉602998670

P粉602998670

发布时间:2026-01-19 12:57:08

|

105人浏览过

|

来源于php中文网

原创

当多个goroutine同时读写非原子变量时必须加锁,否则触发data race;常见场景包括全局计数器、并发读写map、结构体字段竞争等。

go初级项目如何处理并发安全_go锁与并发实战

Go里什么时候必须加锁

当多个 goroutine 同时读写同一个变量(尤其是写),且该变量不是原子类型或未用同步原语保护时,就存在数据竞争——go run -race 会报 Data race。常见场景包括:
• 全局计数器(如 var count int)被多个 goroutine 自增
• map 被并发读写(即使只是 m[key] = valueval := m[key] 交替发生)
• 结构体字段被不同 goroutine 修改而无同步机制
• 使用 sync/atomic 但误用了非原子操作(比如对 int64atomic.LoadInt32

mutex 和 RWMutex 怎么选

sync.Mutex 是最常用的选择,适合读写都较频繁、或写操作不可忽略的场景;sync.RWMutex 在「读多写少」时更高效,但要注意:它不保证写操作的绝对优先级,可能被持续读请求饿死。
• 写操作占比 > 10%,直接用 Mutex
• 读操作远多于写(比如配置缓存、白名单 map),且写入极少(如启动时加载 + 运行时偶尔刷新),用 RWMutex
• 不要嵌套调用 RWMutex.RLock() 多次再 Unlock() —— 它不是可重入锁,重复 RLock() 没问题,但每个 RLock() 都要配对 RUnlock(),否则会死锁
defer mu.Unlock() 必须紧跟在 mu.Lock()mu.RLock() 后,否则可能漏解锁

map 并发读写错误怎么修

Go 的原生 map 不是并发安全的,运行时报错通常是:fatal error: concurrent map read and map writeconcurrent map iteration and map write
• 最简单修复:用 sync.RWMutex 包裹整个 map 操作
• 更轻量替代:用 sync.Map,但它只适合「低频写 + 高频读」且 key 类型为 stringint 等常见类型;注意:sync.Map 不支持遍历(range),必须用 Range() 方法传函数回调
• 切忌用 map + atomic.Value 手动包装——atomic.Value 只能存「不可变值」,map 本身是引用类型,替换整个 map 指针可以,但无法解决内部元素并发修改问题

TalkMe
TalkMe

与AI语伴聊天,练习外语口语

下载
var cache = struct {
	mu sync.RWMutex
	data map[string]int
}{data: make(map[string]int)}

func Get(key string) (int, bool) {
	cache.mu.RLock()
	defer cache.mu.RUnlock()
	v, ok := cache.data[key]
	return v, ok
}

func Set(key string, val int) {
	cache.mu.Lock()
	defer cache.mu.Unlock()
	cache.data[key] = val
}

初学者最容易忽略的锁边界

锁的粒度和作用域比“加不加锁”更重要。新手常犯的错:
• 把锁放在函数开头、defer Unlock() 放在结尾,但中间有耗时操作(如 HTTP 请求、数据库查询),导致锁持有时间过长,成为性能瓶颈
• 在循环内反复加锁/解锁,而不是把整个循环包进临界区(如果逻辑允许)
• 锁保护了变量,却忘了保护其依赖状态——比如一个 isReady bool 和一个 data []byte,两个字段需同时更新,只锁其中一个没用
• 在方法接收者上用指针接收但忘记锁字段所属结构体实例(即锁对象和被锁数据不在同一内存上下文)

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

318

2023.08.02

counta和count的区别
counta和count的区别

Count函数用于计算指定范围内数字的个数,而CountA函数用于计算指定范围内非空单元格的个数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

197

2023.11.20

counta和count的区别
counta和count的区别

Count函数用于计算指定范围内数字的个数,而CountA函数用于计算指定范围内非空单元格的个数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

197

2023.11.20

scripterror怎么解决
scripterror怎么解决

scripterror的解决办法有检查语法、文件路径、检查网络连接、浏览器兼容性、使用try-catch语句、使用开发者工具进行调试、更新浏览器和JavaScript库或寻求专业帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

187

2023.10.18

500error怎么解决
500error怎么解决

500error的解决办法有检查服务器日志、检查代码、检查服务器配置、更新软件版本、重新启动服务、调试代码和寻求帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

288

2023.10.25

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

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

196

2025.06.09

golang结构体方法
golang结构体方法

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

189

2025.07.04

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

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

196

2025.06.09

PHP WebSocket 实时通信开发
PHP WebSocket 实时通信开发

本专题系统讲解 PHP 在实时通信与长连接场景中的应用实践,涵盖 WebSocket 协议原理、服务端连接管理、消息推送机制、心跳检测、断线重连以及与前端的实时交互实现。通过聊天系统、实时通知等案例,帮助开发者掌握 使用 PHP 构建实时通信与推送服务的完整开发流程,适用于即时消息与高互动性应用场景。

3

2026.01.19

热门下载

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

精品课程

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

共32课时 | 3.9万人学习

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

共10课时 | 0.8万人学习

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

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