Путаница в CreateMutex - PullRequest
       3

Путаница в CreateMutex

4 голосов
/ 25 февраля 2011

Пусть говорит, что я вызываю CreateMutex.

HANDLE h;
h=CreateMutex(NULL, TRUE, NULL);
waitforsingleobject(h, INFINITE);
////Random Code
ReleaseMutex(h);

Предполагая, что у меня запущено несколько потоков, первый поток, который достигнет функции createmutex, по существу блокирует все остальные потоки из секции // случайного кода до тех пор, пока не освободится мьютексназывается правильно?

Ответы [ 4 ]

14 голосов
/ 25 февраля 2011

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

Чтобы это исправить, либо пусть h будет глобальным дескриптором, к которому имеют доступ все потоки, и вызовет CreateMutex один раз вне общего кода, либо предоставьте CreateMutex имя (третий аргумент).В последнем случае последующие вызовы CreateMutex вернут дескриптор существующего мьютекса.

1 голос
/ 25 февраля 2011

Принимая во внимание, что вы создаете безымянный мьютекс, каждый поток создаст свой собственный безымянный мьютекс и при создании принимает на себя ответственность. Поскольку каждый поток имеет свой собственный мьютекс, все потоки смогут работать параллельно.

Таким образом, вы должны создать мьютекс один раз для всех потоков, если вы хотите, чтобы он был неназванным. Просматривая свой код, вы также должны проверить, успешно ли создано мьютекс.

Затем в функции, которая вызывается из нескольких потоков, вызывается WaitForSingleObject для ранее созданного мьютекса.

Проверьте возвращенный результат, если он вернулся, потому что вы получили владелец мьютекса или ожидание было прервано, потому что мьютекс был отменен.

Убедитесь, что вы вызываете ReleaseMutex для дескриптора мьютекса, если у вас есть владелец. Вероятно, вам следует подумать об использовании RAII для управления мьютексом по многим причинам (чтобы убедиться, что мьютекс правильно освобождается при возникновении исключений или при вставке оператора возврата перед ReleaseMutex, чтобы назвать лишь несколько).

Когда мьютекс больше не нужен, обязательно вызовите CloseHandle для MutexHandle.

Пример использования мьютексов см. Здесь: «Использование объектов мьютекса»

Базовую многопоточную оболочку см. Здесь: Использование потоков

1 голос
/ 25 февраля 2011

Поскольку вы не указываете имя мьютекса, каждый поток создаст свой собственный отдельный мьютекс, о котором другие потоки не узнают.

Критическая секция будет лучшим выбором в вашем сценарии.

0 голосов
/ 25 февраля 2011

Только если одна и та же ссылка мьютекса является общей для всех потоков / процессов. Вы не делитесь этим, вы создаете это каждый раз. Вам нужно будет назвать его так, чтобы все они получали одинаковый мьютекс для работы вашего кода.

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