Может кто-нибудь объяснить это замечание в документации MSDN CreateMutex () о флаге bInitialOwner? - PullRequest
4 голосов
/ 03 июня 2010

Документация MSDN CreatMutex () (http://msdn.microsoft.com/en-us/library/ms682411%28VS.85%29.aspx) содержит следующее замечание в конце:

Два или более процесса могут вызывать CreateMutex для создания мьютекса с одинаковым именем. Первый процесс фактически создает мьютекс, а последующие процессы с достаточными правами доступа просто открывают дескриптор существующего мьютекса. Это позволяет нескольким процессам получать дескрипторы одного и того же мьютекса, одновременно снимая с пользователя ответственность за обеспечение того, чтобы процесс создания был запущен первым. При использовании этого метода вы должны установить флаг bInitialOwner в FALSE; в противном случае может быть трудно определить, какой процесс имеет первоначальное право собственности.

Может кто-нибудь объяснить проблему с использованием bInitialOwner = TRUE?

Ранее в той же документации предлагался вызов GetLastError (), который позволит вам определить, создал ли вызов CreateMutex () мьютекс или просто вернул новый дескриптор существующему мьютексу:

Возвращаемое значение

Если функция завершается успешно, возвращаемое значение является дескриптором вновь созданного объекта мьютекса.

Если функция завершается ошибкой, возвращаемое значение равно NULL. Чтобы получить расширенную информацию об ошибке, вызовите GetLastError.

Если мьютекс является именованным мьютексом и объект существовал до этого вызова функции, возвращаемое значение является дескриптором существующего объекта, GetLastError возвращает ERROR_ALREADY_EXISTS, bInitialOwner игнорируется, и вызывающему потоку не предоставляется право собственности. Однако, если у вызывающей стороны есть ограниченные права доступа, функция завершится с ошибкой ERROR_ACCESS_DENIED, и вызывающая сторона должна использовать функцию OpenMutex.

Ответы [ 3 ]

3 голосов
/ 07 июня 2010

Использование bInitialOwner объединяет два этапа в один: создание мьютекса и получение мьютекса. Если несколько людей могут создавать мьютекс одновременно, первый шаг может закончиться неудачей, а второй может быть успешным.

Как упоминали другие авторы, это не строго проблема, так как вы получите ERROR_ALREADY_EXISTS, если кто-то другой создаст его первым. Но затем вы должны различать случаи «не удалось создать или найти мьютекс» и «не удалось получить мьютекс; повторите попытку позже», просто используя код ошибки. Это сделает ваш код трудным для чтения и станет проще.

Напротив, когда bInitialOwner имеет значение FALSE, процесс намного проще:

result = create mutex()
if result == error:
   // die
result = try to acquire mutex()
if result == error:
   // try again later
else:
   // it worked!
1 голос
/ 03 июня 2010

Ну, не уверен, что есть настоящая проблема. Но если вы установите аргумент TRUE в обоих процессах, то у вас будет , чтобы проверить значение GetLastError (), чтобы проверить, действительно ли вы в конечном итоге приобрели право собственности. Это будет первым пришел - первым обслужен. Полезно, возможно, только если вы используете именованный мьютекс для реализации экземпляра одноэлементного процесса.

0 голосов
/ 07 июня 2010

Этот флаг используется для создания мьютекса в собственном состоянии - успешный вызывающий объект атомарно создаст объект синхронизации, а также получит блокировку перед возвратом в случае, если вызывающий должен быть уверен, что между созданием не может возникнуть состояние гонки. объект и его приобретение.

Ваш протокол определит, нужно ли вам когда-либо делать это за одну атомарную операцию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...