使用sync.Mutex可保护共享资源,防止多goroutine并发访问导致数据竞争,通过加锁确保同一时间仅一个goroutine操作变量。

在Golang中,sync 包是实现并发控制的核心工具之一。它提供了多种同步原语,帮助开发者安全地管理多个goroutine之间的资源共享与执行顺序。掌握这些机制,能有效避免竞态条件、数据竞争等问题。
使用 sync.Mutex 保护共享资源
当多个goroutine需要访问同一个变量或结构体时,必须通过互斥锁来保证同一时间只有一个goroutine可以操作该资源。
示例:多个goroutine同时增加计数器
var counter intvar mu sync.Mutexfunc worker() { for i := 0; i < 1000; i++ { mu.Lock() counter++ mu.Unlock() }}func main() { var wg sync.WaitGroup for i := 0; i < 5; i++ { wg.Add(1) go func() { defer wg.Done() worker() }() } wg.Wait() fmt.Println("最终计数:", counter) // 输出 5000}
关键点:
立即学习“go语言免费学习笔记(深入)”;
每次修改 counter 前调用 mu.Lock(),操作完成后立即解锁确保 Unlock 在 defer 中调用,防止死锁
使用 sync.RWMutex 提升读性能
对于读多写少的场景,RWMutex 允许多个读操作并发进行,仅在写时独占访问。
示例:缓存读写控制
var config map[string]stringvar rwMu sync.RWMutexfunc readConfig(key string) string { rwMu.RLock() defer rwMu.RUnlock() return config[key]}func updateConfig(key, value string) { rwMu.Lock() defer rwMu.Unlock() config[key] = value}
说明:
读操作使用 RLock/RLock写操作仍需普通 Lock/Unlock适用于配置加载、状态查询等高频读取场景
使用 sync.WaitGroup 等待所有任务完成
WaitGroup 用于等待一组并发任务结束,常配合goroutine使用。
典型结构:
var wg sync.WaitGroupfor _, item := range items { wg.Add(1) go func(val interface{}) { defer wg.Done() process(val) }(item)}wg.Wait() // 阻塞直到所有 Done 被调用
注意:
Add 必须在goroutine启动前调用,否则可能产生竞态传递循环变量时要复制值或作为参数传入闭包
使用 sync.Once 确保初始化只执行一次
某些初始化操作(如加载配置、连接数据库)只需运行一次,Once.Do() 可保证线程安全的单次执行。
var once sync.Oncevar instance *Databasefunc GetDB() *Database { once.Do(func() { instance = connectToDatabase() }) return instance}
无论多少goroutine同时调用 GetDB(),内部函数只会执行一次。
基本上就这些常用模式。合理组合 Mutex、WaitGroup 和 Once,就能应对大多数并发控制需求。关键是理解每种原语的设计目的,并避免过度同步影响性能。
以上就是如何在Golang中使用sync包实现并发控制的详细内容,更多请关注创想鸟其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1412051.html
微信扫一扫
支付宝扫一扫