Я использую CreateMutex для создания глобального мьютекса, чтобы предотвратить запуск нескольких экземпляров приложения. При первом запуске CreateMutex возвращает дескриптор, а 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.