首页 > 解决方案 > 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.

标签: c++winapimutex

解决方案


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

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

当您调用CloseHandle时,没有更多进程持有互斥锁的句柄,因此系统将其销毁。


推荐阅读