goProject/trunk/goutil/syncUtil/locker.go
皮蛋13361098506 1b77f62820 初始化项目
2025-01-06 16:01:02 +08:00

91 lines
1.9 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package syncUtil
import (
"fmt"
"runtime/debug"
"sync"
"time"
)
// 写锁对象
type Locker struct {
locking bool
prevStack []byte
mutex sync.Mutex
}
// 内部锁
// 返回值:
// 加锁是否成功
func (this *Locker) lock() bool {
this.mutex.Lock()
defer this.mutex.Unlock()
// 如果已经被锁定,则返回失败
if this.locking {
return false
}
// 否则进行锁定,并返回成功
this.locking = true
// 记录Stack信息
if if_record_stack_info {
this.prevStack = debug.Stack()
}
return true
}
// 尝试加锁,如果在指定的时间内失败,则会返回失败;否则返回成功
// timeout:指定的毫秒数,timeout<=0则将会死等
// 返回值:
// 成功或失败
// 如果失败,返回上一次成功加锁时的堆栈信息
// 如果失败,返回当前的堆栈信息
func (this *Locker) Lock(timeout int) (successful bool, prevStack string, currStack string) {
timeout = getTimeout(timeout)
// 遍历指定的次数(即指定的超时时间)
for i := 0; i < timeout; i++ {
// 如果锁定成功,则返回成功
if this.lock() {
successful = true
break
}
// 如果锁定失败则休眠1ms然后再重试
time.Sleep(time.Millisecond)
}
// 如果时间结束仍然是失败,则返回上次成功的堆栈信息,以及当前的堆栈信息
if successful == false {
if this.prevStack != nil && len(this.prevStack) > 0 {
prevStack = string(this.prevStack)
}
currStack = string(debug.Stack())
}
return
}
// 锁定(死等方式)
func (this *Locker) WaitLock() {
successful, prevStack, currStack := this.Lock(0)
if successful == false {
fmt.Printf("Locker.WaitLock():{PrevStack:%s, currStack:%s}\n", prevStack, currStack)
}
}
// 解锁
func (this *Locker) Unlock() {
this.mutex.Lock()
defer this.mutex.Unlock()
this.locking = false
}
// 创建新的锁对象
func NewLocker() *Locker {
return &Locker{}
}