即使ERROR_ALREADY_EXISTS,CreateMutex()似乎也会获取互斥

CreateMutex() seems to acquire mutex even when ERROR_ALREADY_EXISTS

本文关键字:获取 ALREADY ERROR EXISTS 即使 CreateMutex      更新时间:2023-10-16

我正在使用CreateMutex创建全局互斥,以防止运行应用程序的多个实例。在第一次运行时,CreateMutex返回handle,GetLastError返回ERROR_SUCCESS,创建并获取互斥。在第二次运行时,CreateMutex也返回一些句柄,但GetLastError返回ERROR_ALREADY_EXISTS。在这种情况下,我会向用户显示一条消息并退出程序。

问题是:当第二个实例等待关闭,然后我关闭第一个实例,然后我尝试运行另一个新实例时,它将无法获取互斥。它也会得到ERROR_ALREADY_EXISTS,但为什么?第一个实例已经关闭,所以互斥锁应该由系统释放。这意味着第二个实例以某种方式阻止了第三个实例获取互斥对象!

在尝试获取互斥对象失败后,添加ReleaseMutex和CloseHandle可以解决此问题。但为什么会有不同呢?

#include <Windows.h>
#include <cstdio>
int main()
{
printf("Startingn");
HANDLE returnedHandle = CreateMutex(NULL, TRUE, TEXT("Global\my_unique_name"));
DWORD lastError = GetLastError();
printf("CreateMutex: %i, GetLastError: %in", returnedHandle, lastError);
if (lastError != ERROR_SUCCESS)
{
printf("Mutex already in use! Cannot run.n");
//why is this needed?
//
//if (returnedHandle != NULL)
//{
//  ReleaseMutex(returnedHandle);
//  CloseHandle(returnedHandle);
//}
}
else
{
printf("This is first instance.n");
//RunRestOfProgram();
}
printf("Press Enter to close.");
getchar();
}

一实例输出:

CreateMutex: 200, GetLastError: 0
This is first instance.
Press Enter to close.

二次实例输出:

CreateMutex: 204, GetLastError: 183
Mutex already in use! Cannot run.
Press Enter to close.

关闭第一个实例但未关闭第二个实例后的第三个实例输出:

CreateMutex: 212, GetLastError: 183
Mutex already in use! Cannot run.
Press Enter to close.

第一个CreateMutex调用创建互斥对象。当您再次调用CreateMutex并且它已经存在时,该函数将打开并向互斥对象返回一个句柄。当你关闭第一个进程时,互斥锁仍然存在,因为第二个进程有它的句柄

在这种情况下不需要ReleaseMutex,只需要CloseHandle调用。

当您调用CloseHandle时,没有更多的进程持有互斥体的句柄,因此系统会破坏它