go runtime_error ai_generated true

fatal error: sync: unlock of unlocked mutex

ID: go/mutex-lock-already-held

Also available as: JSON · Markdown · 中文
85%Fix Rate
85%Confidence
1Evidence
2023-01-15First Seen

Version Compatibility

VersionStatusIntroducedDeprecatedNotes
Go 1.18 active
Go 1.19 active
Go 1.20 active
Go 1.21 active
Go 1.22 active

Root Cause

Calling Unlock() on a sync.Mutex that was not locked by the same goroutine, or double-unlocking a mutex.

generic

中文

在同一个协程中对未锁定的 sync.Mutex 调用 Unlock(),或者对同一个互斥锁重复解锁。

Official Documentation

https://pkg.go.dev/sync#Mutex

Workarounds

  1. 95% success Always pair Lock() and Unlock() in the same function, using defer immediately after Lock() to avoid mismatches
    Always pair Lock() and Unlock() in the same function, using defer immediately after Lock() to avoid mismatches
  2. 85% success Use sync.Mutex.TryLock() (Go 1.18+) to check if lock is held before unlocking, but prefer structured patterns
    Use sync.Mutex.TryLock() (Go 1.18+) to check if lock is held before unlocking, but prefer structured patterns

中文步骤

  1. 始终在同一个函数中配对 Lock() 和 Unlock(),在 Lock() 后立即使用 defer 以避免不匹配
  2. 使用 sync.Mutex.TryLock()(Go 1.18+)在解锁前检查锁是否被持有,但推荐使用结构化模式

Dead Ends

Common approaches that don't work:

  1. 75% fail

    Defer runs even if the lock was never acquired (e.g., due to early return), causing an unlock of an unlocked mutex.

  2. 90% fail

    The Go runtime checks that the unlocking goroutine is the same one that locked it; cross-goroutine unlocks panic.