c++ - CreateMutex() seems to acquire mutex even when ERROR_ALREADY_EXISTS
问题描述
I am using CreateMutex to create global mutex to prevent running multiple instances of an application. On first run CreateMutex returns handle and GetLastError returns ERROR_SUCCESS, the mutex is created and acquired. On second run CreateMutex also returns some handle, but GetLastError returns ERROR_ALREADY_EXISTS. In that case I show a message to user and exit the program.
The problem: when that second instance is waiting to be closed, and then I close the first instance, and then I try to run another new instance, it will fail to acquire the mutex. It will also get ERROR_ALREADY_EXISTS, but why? The first instance is already closed, so the mutex should be released by system. That means that the second instance is somehow preventing the third to acquire the mutex!
The problem is solved by adding ReleaseMutex and CloseHandle after failed attempt to acquire mutex. But why does it make a difference?
#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();
}
First instance output:
CreateMutex: 200, GetLastError: 0
This is first instance.
Press Enter to close.
Second instance output:
CreateMutex: 204, GetLastError: 183
Mutex already in use! Cannot run.
Press Enter to close.
Third instance output, after closing first instance but not closing second instance:
CreateMutex: 212, GetLastError: 183
Mutex already in use! Cannot run.
Press Enter to close.
解决方案
第一次CreateMutex
调用创建互斥体。当您CreateMutex
再次调用并且它已经存在时,该函数将打开并返回互斥锁的句柄。当您关闭第一个进程时,互斥锁仍然存在,因为第二个进程有一个句柄。
ReleaseMutex
在这种情况下不需要,只需要CloseHandle
调用。
当您调用CloseHandle
时,没有更多进程持有互斥锁的句柄,因此系统将其销毁。
推荐阅读
- python - 如何更新纯函数?
- java - Spring Boot,如何在具有 EmbeddedId 的表中插入新记录
- amazon-web-services - 从第三方获取数据到 EC2 是否被视为入站数据?
- postgresql - Postgres 不接受端口 5432 上的 TCP/IP
- php - Yii2 同一模型的多个实例 - 错误调用数组上的成员函数 formName()
- excel - 如何在excel中选择第二行项目并粘贴到另一个excel表中?
- ruby - 使用 HTTParty (Ruby/HTTParty) 的正文中的语法错误
- java - Java - 如何反序列化为逻辑相同的类?
- scala - 使用 Scio 部署 DataFlow 作业
- javascript - 在 Express / EJS 应用程序中添加第二个 JS 文件