1 Star 0 Fork 0

menuiis / gkit

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
recursive_mutex.go 1.17 KB
一键复制 编辑 原始数据 按行查看 历史
menuis 提交于 2024-04-22 10:18 . init
package mutex
import (
"fmt"
"sync"
"sync/atomic"
"gitee.com/menciis/gkit/internal/sys/goid"
)
// RecursiveMutex 包装一个Mutex,实现可重入
type RecursiveMutex struct {
sync.Mutex
owner int64 // 当前持有锁的goroutine id
recursion int64 // 这个goroutine 重入的次数
}
func (m *RecursiveMutex) Lock() {
gid := goid.GetGID()
// 如果当前持有锁的goroutine就是这次调用的goroutine,说明是重入
if atomic.LoadInt64(&m.owner) == gid {
atomic.AddInt64(&m.recursion, 1)
return
}
m.Mutex.Lock()
// 获得锁的goroutine第一次调用,记录下它的goroutine id,调用次数加1
atomic.StoreInt64(&m.owner, gid)
atomic.StoreInt64(&m.recursion, 1)
}
func (m *RecursiveMutex) Unlock() {
gid := goid.GetGID()
// 非持有锁的goroutine尝试释放锁,错误的使用
if atomic.LoadInt64(&m.owner) != gid {
panic(fmt.Sprintf("wrong the owner(%d): %d!", m.owner, gid))
}
// 调用次数减1
recursion := atomic.AddInt64(&m.recursion, -1)
if recursion != 0 { // 如果这个goroutine还没有完全释放,则直接返回
return
}
// 此goroutine最后一次调用,需要释放锁
atomic.StoreInt64(&m.owner, -1)
m.Mutex.Unlock()
}
Go
1
https://gitee.com/menciis/gkit.git
git@gitee.com:menciis/gkit.git
menciis
gkit
gkit
4f74120a101e

搜索帮助