CreateMutex() 似乎在 ERROR_ALREADY_EXISTS 时获得互斥锁
CreateMutex() seems to acquire mutex even when ERROR_ALREADY_EXISTS
我正在使用 CreateMutex 创建全局互斥体以防止 运行 绑定一个应用程序的多个实例。在第一个 运行 CreateMutex returns 句柄和 GetLastError returns ERROR_SUCCESS 上,创建并获取互斥量。第二个 运行 CreateMutex 也 returns 一些句柄,但 GetLastError returns ERROR_ALREADY_EXISTS。在那种情况下,我会向用户显示一条消息并退出程序。
问题:当第二个实例等待关闭,然后我关闭第一个实例,然后我尝试 运行 另一个新实例时,它将无法获取互斥锁。它也会得到 ERROR_ALREADY_EXISTS,但为什么呢?第一个实例已经关闭,因此互斥锁应该由系统释放。这意味着第二个实例以某种方式阻止了第三个实例获取互斥体!
问题已通过在尝试获取互斥锁失败后添加 ReleaseMutex 和 CloseHandle 解决。但为什么会有所不同?
#include <Windows.h>
#include <cstdio>
int main()
{
printf("Starting\n");
HANDLE returnedHandle = CreateMutex(NULL, TRUE, TEXT("Global\my_unique_name"));
DWORD lastError = GetLastError();
printf("CreateMutex: %i, GetLastError: %i\n", 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
并且它已经存在时,该函数将打开并且 returns 互斥量的句柄。当您关闭第一个进程时,互斥量仍然存在,因为第二个进程有它的句柄。
在这种情况下不需要 ReleaseMutex
,只需要调用 CloseHandle
。
当您调用 CloseHandle
时,不再有进程持有互斥锁的句柄,因此系统将销毁它。
我正在使用 CreateMutex 创建全局互斥体以防止 运行 绑定一个应用程序的多个实例。在第一个 运行 CreateMutex returns 句柄和 GetLastError returns ERROR_SUCCESS 上,创建并获取互斥量。第二个 运行 CreateMutex 也 returns 一些句柄,但 GetLastError returns ERROR_ALREADY_EXISTS。在那种情况下,我会向用户显示一条消息并退出程序。
问题:当第二个实例等待关闭,然后我关闭第一个实例,然后我尝试 运行 另一个新实例时,它将无法获取互斥锁。它也会得到 ERROR_ALREADY_EXISTS,但为什么呢?第一个实例已经关闭,因此互斥锁应该由系统释放。这意味着第二个实例以某种方式阻止了第三个实例获取互斥体!
问题已通过在尝试获取互斥锁失败后添加 ReleaseMutex 和 CloseHandle 解决。但为什么会有所不同?
#include <Windows.h>
#include <cstdio>
int main()
{
printf("Starting\n");
HANDLE returnedHandle = CreateMutex(NULL, TRUE, TEXT("Global\my_unique_name"));
DWORD lastError = GetLastError();
printf("CreateMutex: %i, GetLastError: %i\n", 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
并且它已经存在时,该函数将打开并且 returns 互斥量的句柄。当您关闭第一个进程时,互斥量仍然存在,因为第二个进程有它的句柄。
ReleaseMutex
,只需要调用 CloseHandle
。
当您调用 CloseHandle
时,不再有进程持有互斥锁的句柄,因此系统将销毁它。