Golang Mutex(互斥锁)讲解

Golang Mutex(互斥锁)讲解


🏗 什么是 Mutex?

Mutex 全称是 Mutual Exclusion(互斥)。 在并发编程中,它是一种锁机制, 用来: ✅ 保护共享资源, ✅ 保证同一时间 只有一个 goroutine 能访问资源, ✅ 避免竞态条件(race condition)

简单说:

当多个 goroutine 要修改同一块数据时,必须用锁,否则数据可能混乱。



🌟 Mutex 在 Go 里的位置

Go 的 sync 包提供了 sync.Mutex,用法简单:

var mu sync.Mutex

它有两个核心方法:

方法作用
mu.Lock()加锁(获得互斥权)
mu.Unlock()解锁(释放互斥权)


🚦 什么时候需要 Mutex?

当你有:

  • 多个 goroutine 读写共享变量

  • 多个 goroutine 修改共享 map、slice、struct

⚠ 注意:只读不写的场景可以用 RWMutex 或不加锁。



🏹 Mutex 的基本用法

import (
    "fmt"
    "sync"
)
​
var (
    mu      sync.Mutex
    counter int
)
​
func increment() {
    mu.Lock()
    counter++
    mu.Unlock()
}

这里: ✅ mu.Lock() 进入临界区(只允许一个 goroutine 进入) ✅ counter++ 是临界操作 ✅ mu.Unlock() 离开临界区(让其他 goroutine 进来)



⚙ 完整示例:多个 goroutine 并发加计数器

package main
​
import (
    "fmt"
    "sync"
)
​
var (
    counter int
    mu      sync.Mutex
    wg      sync.WaitGroup
)
​
func main() {
    for i := 0; i < 1000; i++ {
        wg.Add(1)
        go func() {
            mu.Lock()
            counter++
            mu.Unlock()
            wg.Done()
        }()
    }
​
    wg.Wait()
    fmt.Println("Final counter:", counter)
}

说明:

  • 启动 1000 个 goroutine,每个 +1

  • mu 保证同时只有一个 goroutine 在修改 counter

  • 最终输出 肯定是 1000(不用锁就不保证了)



🛡 为什么不用锁会出错?

因为 counter++ 其实是:

  1. 读 counter

  2. +1

  3. 写回 counter

多个 goroutine 并发做这个,可能出现:

  • 都读到旧值(比如 0)

  • 都写回新值(比如 1),但丢失了其他更新

结果:

丢失更新(lost update)

用锁可以强制它们排队,一个一个来。



💥 Mutex 常见坑

1️⃣ 忘记 Unlock

mu.Lock()
// 出错 return 或 panic,没有解锁

👉 最好用 defer

mu.Lock()
defer mu.Unlock()

2️⃣ 死锁 两个 goroutine 互相等对方解锁,谁也走不动。

mu1.Lock()
mu2.Lock()
// ... 业务
mu2.Unlock()
mu1.Unlock()

如果反过来:

mu2.Lock()
mu1.Lock()

就可能互相卡住。

👉 建议:锁顺序一致


3️⃣ 性能过低 所有 goroutine 都串行化,等同于单线程。

👉 如果只是读,考虑用:

  • sync.RWMutex:允许多个读,写时独占。

  • atomic 包:对于简单数值加减更高效。



🌈 RWMutex 简单对比

类型适用场景
sync.Mutex读写都少,改动大,串行化
sync.RWMutex多读少写,允许并行读

RWMutex 用法:

var rw sync.RWMutex
​
rw.RLock()  // 读锁
rw.RUnlock()
rw.Lock()   // 写锁
rw.Unlock()


🧪 更强用法:带超时或尝试锁(Go 没有)

注意:

  • Go 的 sync.Mutex 没有 TryLock() 或带超时的锁。

  • 如果需要这些,可以用:

    • sync/atomic

    • 第三方库(如 github.com/abiosoft/semaphore)

    • 自己用 channel 实现控制。



📦 总结

核心概念
sync.Mutex 提供互斥锁
Lock() 加锁,Unlock() 解锁
保护共享资源,防止数据竞争
defer Unlock() 防止忘记解锁
多读场景用 RWMutex 更高效
注意避免死锁,保持锁顺序一致

👉 立即点击链接,开启你的全栈开发之路:Golang全栈开发完整课程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值