乐趣区

关于go:golang实现简单的可重入锁

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.")

}
退出移动版