Go 中 sync.Mutex 是轻量互斥锁,需在临界区成对调用 Lock/Unlock;推荐 defer 解锁,结构体中嵌入 mutex 并传指针;避免值复制和死锁;读多写少时可用 RWMutex 提升性能。

在 Go 语言中,sync.Mutex 是最常用、最轻量的互斥锁机制,用于保护共享变量,防止多个 goroutine 同时读写导致数据竞争(data race)。正确使用 mutex 的关键是:**只在真正需要同步的临界区加锁,并确保成对调用 Lock() 和 Unlock()**。
sync.Mutex 提供两个核心方法:Lock()(阻塞获取锁)和 Unlock()(释放锁)。它不区分读写,属于“重量级”独占锁——一旦被某个 goroutine 持有,其他 goroutine 必须等待。
Lock() 而忘记 Unlock()。defer mu.Unlock() 确保释放,尤其在函数有多个返回路径时。最常见做法是把 sync.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
}这样所有对 value 的修改和读取都经过锁保护,消除了并发读写冲突。注意:不能将 Counter 值类型变量直接传参(会复制 mutex),应始终传递指针。
立即学习“go语言免费学习笔记(深入)”;
锁太粗会导致性能瓶颈,锁太细或漏锁则起不到保护作用。还要警惕隐式复制:
var c Counter; go c.Inc() —— c 被复制,每个 goroutine 操作的是独立副本的 mu,完全没效果。mu.Lock(); if err != nil { return }; mu.Unlock() —— 错误提前返回时锁未释放,造成后续 goroutine 永久阻塞。go vet -race 静态检测数据竞争;运行时开启 -race 标志(go run -race main.go)可动态发现多数竞态问题。若共享资源读操作远多于写操作,可用 sync.RWMutex 提升并发读性能:
RLock() 和 RUnlock() 允许多个 goroutine 同时读;Lock() 和 Unlock() 仍为独占写锁,会阻塞所有读写;RWMutex 不是锁升级机制——不能在已持 RLock() 的 goroutine 中直接调用 Lock(),否则死锁。例如缓存结构体中,Get() 用 RLock(),Set() 用 Lock(),能显著提升高并发读场景吞吐量。
以上就是如何使用Golang实现mutex互斥锁_保证共享资源安全访问的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号