如何锁定功能

use*_*697 -3 mutex go

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
}
Run Code Online (Sandbox Code Playgroud)

我有一个在我的应用程序中被多次调用的 HandleConnect 我想锁定句柄,因为如果有很多调用,我希望只有一个会执行登录逻辑当我运行它时,我收到一个错误 致命错误:同步:解锁未锁定的互斥锁

我该如何解决?

Fli*_*mzy 7

您的代码中有竞争条件。您正在使用全局变量(就目前而言这很好),但随后您会不断重置互斥锁变量:

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
}
Run Code Online (Sandbox Code Playgroud)

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

func handle() bool {
    mutex.Lock()
    defer mutex.Unlock()
    ....some logic.... do login...
    return true
}
Run Code Online (Sandbox Code Playgroud)

为了可视化问题,假设您有一个 goroutine 执行以下步骤:

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

一切都很好。

但是现在假设您有两个 groutine,AB同时运行:

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