如何锁定功能?

时间:2018-12-10 16:20:57

标签: go mutex

var mutex sync.Mutex
func main() {
     handle()
    go register()
}

func register(){
   myObject.OnEvent().DoFunc(HandleConnect)
}
func HandleConnect(){
    handle()
}
func handle() bool {

    mutex = sync.Mutex{}
    mutex.Lock()
    defer mutex.Unlock()
    ....some logic.... do login...
    return true
}

我的HandleConnect在我的应用程序中被多次调用 我想锁定该句柄,因为如果有很多呼叫,我希望只有一个可以执行登录逻辑 运行时出现错误 严重错误:同步:解锁的互斥锁解锁

我该如何解决?

1 个答案:

答案 0 :(得分:4)

您的代码中存在竞争条件。您正在使用全局变量(就目前而言还可以),但是随后您会不断重置互斥量变量:

func handle() bool {
    mutex = sync.Mutex{} // Here you are re-initializing the mutex every time
    mutex.Lock()
    defer mutex.Unlock()
    ....some logic.... do login...
    return true
}

相反,只需不要重置变量:

func handle() bool {
    mutex.Lock()
    defer mutex.Unlock()
    ....some logic.... do login...
    return true
}

要形象地看待问题,请想象您有一个执行以下步骤的goroutine:

  1. 重置互斥锁。 mutex = sync.Mutex{}
  2. 锁定互斥锁。 mutex.Lock()
  3. 做东西...some logic....
  4. 释放锁。 defer mutex.Unlock()

一切都很好。

但是现在想象一下,您同时运行两个 A B 程序:

  1. A 重置互斥锁:mutex = sync.Mutex{}
  2. A 锁定互斥锁:mutex.Lock()
  3. A 做事
  4. B 重置互斥锁:mutex = sync.Mutex{} 注意:现在,所有goroutine互斥锁都已解锁,因为它是全局变量!
  5. A 解锁互斥锁并崩溃,因为它已被解锁