Главная arrow С++ (часть 3) arrow Использование мьютекса для синхронизации потоков

Использование мьютекса для синхронизации потоков

Как уже отмечалось, мьютекс — это специальный семафор, который разрешает только одному потоку доступ к ресурсу в любой конкретный момент времени. Прежде чем использовать мьютекс, его нужно создать с помощью функции createMutex о, чей прототип приведен далее.
jgfljDLE CreateMutex (LPSECURITYATTRIBUTES secAttr, BOOL acquire, LPCSTR name);
Параметр secAttr — это указатель на атрибуты защиты. Если secAttr равен JJULL, применяется дескриптор защиты по умолчанию.
Если создающийся поток хочет контролировать мьютекс, параметр acquire должен быть равен true, в противном случае — false.
Параметр name указывает на строку, которая становится именем объекта-мьютекса. Мьютексы — глобальные объекты и могут применяться в разных процессах. Если каждый из двух процессов откроет мьютекс с одним и тем же именем, оба будут ссылаться на один и тот же мьютекс. В этом случае оба процесса можно синхронизировать. Имя может быть NULL, тогда семафор локализован в одном процессе.
Функция createMutex () возвращает дескриптор семафора, если завершается успешно, или NULL при возникновении ошибки. Дескриптор мьютекса автоматически закрывается, когда завершается основной процесс. Вы можете явно закрыть дескриптор мьютекса, если он больше не нужен, вызвав функцию CloseHandle().
Создав семафор, вы используете его в дальнейшем с помощью двух функций: WaitForSingleObject() и ReleaseMutex(). Их прототипы приведены далее.
DWORD WaitForSingleObject(HANDLE hObject, DWORD howLong); BOOL ReleaseMutex(HANDLE hMutex);
Функция WaitForSingleObject о ждет объект синхронизации. Она не возвращается в программу до тех пор, пока объект не станет доступным или не исчерпается отведенное время. Если она используется для работы с мьютек-сом, то параметр hobject содержит дескриптор мьютекса. Параметр howLong задает время ожидания в мс для вызывающей объект процедуры. Как только время истекло, возвращается ошибка истечения времени ожидания (time-out error). Для неопределенно долгого ожидания используйте значение INFINITE. При успешном завершении функция возвращает значение WAIT_OBJECT_O (это означает, что доступ предоставлен). Если же исчерпано время ожидания, возвращается значение WAIT_TIMEOUT.
Функция ReleaseMutex о освобождает мьютекс и позволяет другому потоку запрашивать его. Параметр hMutex содержит дескриптор мьютекса. Функция возвращает ненулевое значение при успешном завершении и 0 — при возникновении ошибки.
Если вы используете мьютекс для управления доступом к разделяемому ресурсу, вставьте фрагмент кода, организующий этот доступ межу вызовами функций WaitForSingleObject () И ReleaseMutex(), как показано В приведенной далее общей схеме (конечно, время ожидания будет разным у различных приложений).
if(WaitForSingleObject(hMutex, 10000)== WAIT_TIMEOUT); { // обработка превышения времени ожидания
}
// доступ к ресурсу ReleaseMutex(hMutex);
Как правило, вы зададите превышение времени ожидания, которое будет больше времени, требующегося для выполнения необходимых действий в вашей программе. Если ошибки превышения времени ожидания будут повторяться при разработке многопоточного приложения, это значит, что вы создали тупиковую ситуацию (deadlock condition). Она возникает, когда один поток ожидает мьютекса, который другой поток никогда не освобождает.