Я пытаюсь понять, что это за состояние гонки, о котором меня предупреждает статья OpenMutex MSDN.Из MSDN:
Если многопоточное приложение должно многократно создавать, открывать и закрывать именованный объект мьютекса, может возникнуть условие гонки.В этой ситуации лучше использовать CreateMutex вместо OpenMutex, потому что CreateMutex открывает мьютекс, если он существует, и создает его, если его нет.
Это же предупреждение содержится в книге Windows Internals 6th.выпуск часть 1:
Windows также поддерживает Ex (расширенные) версии API-интерфейсов - CreateEventEx, CreateMutexEx, CreateSemaphoreEx - которые добавляют еще один аргумент для указания маски доступа.Это позволяет приложениям правильно использовать списки контроля доступа (DACL) для защиты своих объектов, не нарушая возможности использовать API создания объектов для открытия дескриптора для них.Вы можете быть удивлены, почему клиентское приложение не просто использует OpenEvent, который поддерживает желаемый аргумент доступа.Использование API открытых объектов приводит к внутреннему состоянию гонки при работе со сбоем в открытом вызове, то есть, когда клиентское приложение пыталось открыть событие до того, как оно было создано.В большинстве приложений такого типа за открытым API следует API-интерфейс create в случае сбоя.К сожалению, не существует гарантированного способа сделать эту операцию создания атомарной, другими словами, чтобы она выполнялась только один раз.Действительно, было бы возможно, чтобы несколько потоков и / или процессов одновременно выполняли API-интерфейс create и все пытались создать событие одновременно.Это условие гонки и дополнительная сложность, необходимая для того, чтобы попытаться справиться с ним, делают использование API открытых объектов неуместным решением проблемы, поэтому вместо этого следует использовать API Ex.
Предположим, что несколько потоковпытаются вызвать OpenMutex () одновременно, и результатом будет сбой.Затем эти потоки будут вызывать CreateMutex (), поэтому первый из них создаст запрошенный мьютекс, а другие откроют его.Это та же самая ситуация, когда несколько потоков пытаются вызвать CreateMutex () без предшествующего OpenMutex.Но если CreateMutex () не является потокобезопасным и возникнет условие гонки, оно также останется в ситуации, не предшествующей OpenMutex ().
Может кто-нибудь объяснить мне, какая ситуация приведет к состоянию гонки?
ОБНОВЛЕНИЕ 1:
В большинстве приложений такого типа за открытым API следует API создания в случае сбоя.К сожалению, не существует гарантированного способа сделать эту операцию создания атомарной, другими словами, чтобы она выполнялась только один раз.Действительно, было бы возможно, чтобы несколько потоков и / или процессов одновременно выполняли API создания и все пытались создать событие одновременно.
Почему это плохая ситуация?После сбоя всех потоков в OpenMutex () они будут вызывать CreateMutex () одновременно.Вызов CreateMutex () одним потоком создаст мьютекс, а другие откроют его.
Поэтому я не могу понять, почему использование OpenMutex () с последующим CreateMutex () - плохая идея?
ОБНОВЛЕНИЕ 2:
Я написал тестовое приложение, которое запускается в нескольких экземплярах.Каждый экземпляр в цикле сначала пытается вызвать OpenMutex (), затем в случае ошибки он вызывает CreateMutex ().В обоих случаях приложение записывает результаты открытия / создания мьютекса, вызывает CloseHandle () и затем переходит к следующей итерации.Я пробовал разное количество экземпляров с разными таймингами (добавляя sleep), но при вызове CreateMutex () или каких-либо неожиданных действиях ошибок нет.
Итак, вопрос остается открытым, зачем использовать OpenMutex () с последующим CreateMutex () это плохая практика?