即使ERROR_ALREADY_EXISTS

时间:2019-01-11 19:11:02

标签: c++ winapi mutex

我正在使用CreateMutex创建全局互斥锁,以防止运行应用程序的多个实例。在第一次运行时,CreateMutex返回handle,而GetLastError返回ERROR_SUCCESS,则创建并获取了互斥锁。在第二次运行时,CreateMutex也返回一些句柄,但GetLastError返回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.

1 个答案:

答案 0 :(得分:4)

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

在这种情况下,不需要

ReleaseMutex,只需调用CloseHandle

调用CloseHandle时,不再有持有互斥量句柄的进程,因此系统将销毁它。