Visual c++ 互斥锁根本不释放

Visual c++ 互斥锁根本不释放,visual-c++,mutex,Visual C++,Mutex,我希望运行一个.exe实例,并在app::InitInstance()中使用互斥,如下所示 在app::ExitInstance()中,我有 int iii = ReleaseMutex(hMutex); 其中hMutex是全局变量:HANDLE hMutex 这是可行的,并且只将应用程序限制为一个实例。但是,在关闭时,我使用GetLastError()收到以下消息:“尝试释放不属于调用方的互斥锁。” 评论 如果调用线程不拥有 互斥对象 线程通过使用 bInitialOwner参数设置为TRU

我希望运行一个.exe实例,并在
app::InitInstance()中使用互斥,如下所示

app::ExitInstance()
中,我有

int iii = ReleaseMutex(hMutex);
其中hMutex是全局变量:
HANDLE hMutex

这是可行的,并且只将应用程序限制为一个实例。但是,在关闭时,我使用
GetLastError()
收到以下消息:“尝试释放不属于调用方的互斥锁。”

评论

如果调用线程不拥有 互斥对象

线程通过使用 bInitialOwner参数设置为TRUE或通过在 调用其中一个等待函数。当线程不再需要 拥有互斥对象,它调用ReleaseMutex函数,以便 另一个线程可以获得所有权

线程可以在对其中一个线程的调用中指定它已经拥有的互斥体 等待在不阻塞其执行的情况下运行。这可以防止 线程自死锁,同时等待一个互斥锁 已经拥有了。但是,要释放其所有权,线程必须调用 每次获得所有权时释放互斥一次(或 通过CreateMutex或等待函数)


在这种情况下,不需要拥有或释放互斥对象,因为您没有进行任何资源保护。但是,您可以对其发出
CloseHandle
,这将减少引用计数,当最后一个句柄关闭时,互斥对象将被销毁。您也不需要调用它,因为操作系统会为您做这件事(并且还会维护引用计数机制)

但是,当第二个实例正在运行时,您可能需要尽快关闭它(可能会显示一个对话框)。在这种情况下,在显示对话框(即“另一个实例正在运行”)之前,必须将其关闭。如果你不这样做,考虑一个场景:

  • 应用程序正常启动
  • 另一个实例(错误地)被启动,新进程检测到它并显示一个对话框(不关闭句柄)
  • 关闭在步骤1中打开的实际应用程序(但不关闭(2)中显示的对话框)
  • 现在,您尝试启动应用程序-它会说应用程序已经在运行-实际上,它并没有运行(只显示一个对话框)
    int iii = ReleaseMutex(hMutex);
    
    HANDLE WINAPI CreateMutex(
      _In_opt_  LPSECURITY_ATTRIBUTES lpMutexAttributes,
      _In_      BOOL bInitialOwner,
      _In_opt_  LPCTSTR lpName
    );