使用sync.Mutex可避免多goroutine并发修改共享变量导致的数据竞争,通过加锁保护临界区,确保同一时间只有一个goroutine能访问共享资源。

在Go语言中,sync.Mutex 是最常用的同步原语之一,用于保护共享资源不被多个goroutine同时访问。下面通过一个简单但典型的示例,展示如何正确使用 sync.Mutex 来避免竞态条件。
问题场景:并发修改共享变量
假设多个goroutine同时对一个全局计数器进行递增操作,如果不加保护,会导致数据竞争:
var counter intfunc worker() { for i := 0; i < 1000; i++ { counter++ // 非原子操作,存在竞态 }}func main() { var wg sync.WaitGroup for i := 0; i < 5; i++ { wg.Add(1) go func() { worker() wg.Done() }() } wg.Wait() fmt.Println("最终计数:", counter) // 结果可能小于预期的5000}
使用 Mutex 保护临界区
通过引入 *sync.Mutex,可以确保同一时间只有一个goroutine能进入临界区:
var ( counter int mu sync.Mutex)func safeWorker() { for i := 0; i < 1000; i++ { mu.Lock() counter++ mu.Unlock() }}
每次修改 counter 前先调用 Lock(),修改完成后立即调用 Unlock(),保证操作的原子性。
立即学习“go语言免费学习笔记(深入)”;
更安全的写法:配合 defer 使用
为防止忘记解锁或在锁持有期间发生 panic 导致死锁,推荐使用 defer mu.Unlock():
func saferWorker() { for i := 0; i < 1000; i++ { mu.Lock() defer mu.Unlock() counter++ }}
虽然这里每次循环都 defer 可能略显冗余,但在复杂逻辑或包含分支、return 的函数中,这种模式能有效避免资源泄漏。
结构体中嵌入 Mutex 的常见模式
实际开发中,Mutex 通常作为结构体字段,用来保护结构体内部状态:
type Counter struct { mu sync.Mutex value int}func (c *Counter) Inc() { c.mu.Lock() defer c.mu.Unlock() c.value++}func (c *Counter) Value() int { c.mu.Lock() defer c.mu.Unlock() return c.value}
这样封装后,所有对外暴露的方法都自动具备线程安全性,调用者无需关心同步细节。
基本上就这些。只要记住:共享资源 + 并发写 = 必须加锁。合理使用 sync.Mutex 能有效防止数据竞争,提升程序稳定性。
以上就是Golang sync包互斥锁使用示例的详细内容,更多请关注创想鸟其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1410716.html
微信扫一扫
支付宝扫一扫