package main
import (
"fmt"
"github.com/petermattis/goid"
"sync"
"sync/atomic"
)
// Go version: V1.21.0
type ReentryMutex struct {
sync.Mutex
owner int64//当前锁的拥有者 goroutineid
reentry int32//重入次数
}
func (r *ReentryMutex)Lock(){
gid:=goid.Get()
//如果锁的拥有者已经是当前goroutine,记录下他已经重入的次数
if atomic.LoadInt64(&r.owner)==gid{
r.reentry++
return
}
r.Mutex.Lock()
atomic.StoreInt64(&r.owner,gid)
//初始化可访问次数
r.reentry=1
}
func (r *ReentryMutex) Unlock(){
gid:=goid.Get()
//如果解锁协程不是当前协程的拥有者,就panic
if atomic.LoadInt64(&r.owner)!=gid{
panic(any(fmt.Sprintf("wrong the owner(%d): %d!",r.owner,gid)))
}
r.reentry--
if r.reentry==0{
atomic.StoreInt64(&r.owner,-1)
r.Mutex.Unlock()
}
}
func main() {
var wg sync.WaitGroup
reentryMutex:=ReentryMutex{}
for i := 0; i < 5; i++ {
wg.Add(1)
go func(index int) {
defer wg.Done()
reentryMutex.Lock()
defer reentryMutex.Unlock()
fmt.Printf("Goroutine %d acquired the lock.\n", index)
reentryMutex.Lock()
defer reentryMutex.Unlock()
fmt.Printf("Goroutine %d acquired the lock again.\n", index)
}(i)
}
wg.Wait()
fmt.Println("All goroutines have finished.")
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。