I want write a mutex with key just like https://github.com/im7mortal/kmutex ,but in different ideas.Just store the mutex in the hashmap.But there are always some deadlock in my code.How can I find the bug? Or are there better ways to write the key mutex?
package kmutex
import (
"sync"
)
type keyMutex struct {
localLockMap map[string]*sync.Mutex
globalLock sync.Mutex
}
func NewKeyMutex() *keyMutex {
return &keyMutex{localLockMap: map[string]*sync.Mutex{}}
}
func (km *keyMutex) Lock(key string) {
km.globalLock.Lock()
wl, ok := km.localLockMap[key]
if !ok {
wl = &sync.Mutex{}
km.localLockMap[key] = wl
}
km.globalLock.Unlock()
wl.Lock()
}
func (km *keyMutex) Unlock(key string) {
km.globalLock.Lock()
wl, ok := km.localLockMap[key]
if !ok {
km.globalLock.Unlock()
return
}
delete(km.localLockMap, key)
km.globalLock.Unlock()
wl.Unlock()
}
and test code is below
func TestKeyMutex1(t *testing.T) {
keyMutex := kmutex.NewKeyMutex()
//var keyMutex sync.Mutex
var count = 0
var wg sync.WaitGroup
var num = 100
for i := 1; i <= num; i++ {
wg.Add(1)
go func(i int) {
defer wg.Done()
keyMutex.Lock("a")
count += i
keyMutex.Unlock("a")
}(i)
}
wg.Wait()
println(count)
}
There are always deadlock in it.After I remove the line delete(km.localLockMap, key)
.The deadlock is gone! But I still cannot understand it