gpt4 book ai didi

go - 如何在无错误的情况下按键编写互斥锁?

转载 作者:IT王子 更新时间:2023-10-29 02:28:18 27 4
gpt4 key购买 nike

我想写一个像https://github.com/im7mortal/kmutex一样的互斥锁。 ,但思路不同。只是将互斥锁存储在hashmap中。但我的代码中总是存在一些死锁。我如何找到错误?还是有更好的方法来编写 key 互斥体?

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()
}

下面是测试代码

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)

}

它总是有死锁。在我删除行 delete(km.localLockMap, key) 之后。死锁消失了!但是还是看不懂

最佳答案

问题确实是删除映射中的互斥量。

考虑在同一个条目(“a”)中按以下顺序运行三个锁(当然是在多个 goroutine 中):

keyMutex.Lock("a") // lock1
keyMutex.Lock("a") // lock2
keyMutex.Lock("a") // lock3
keyMutex.Unlock("a") // unlock1
keyMutex.Unlock("a") // unlock2
keyMutex.Unlock("a") // unlock3

lock1在map中创建一个mutex,然后lock2lock3获取相同的mutex,阻塞在mutex的Lock上。 unlock1 找到互斥量,将其解锁并将其从映射中移除,解锁 lock2(或 lock3,但为了讨论起见,假设它是锁2)。但是当 unlock2unlock3 运行时,它在映射中发现没有互斥体,没有解锁任何东西,并保持 lock3 阻塞,因此出现死锁。

从映射中删除互斥量的行根本没有意义:互斥量是可重用的,在上下文中,只有对相同的条目使用相同的互斥量才是明智的。

关于go - 如何在无错误的情况下按键编写互斥锁?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55988340/

27 4 0