91 lines
1.9 KiB
Go
91 lines
1.9 KiB
Go
|
|
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{}
|
|||
|
|
}
|