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 时,不再有进程持有互斥锁的句柄,因此系统将销毁它。