Главная страница Случайная страница КАТЕГОРИИ: АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника |
Мьютексы
Объекты типа мьютекс используют для получения эксклюзивного доступа к какому-либо ресурсу. По действию этот объект во многом напоминает критическую секцию, однако в отличие от нее он может работать с потоками из разных процессов, и при работе с ним можно использовать все возможности Wait-функций которых нет у критических секций: задавать время ожидания, использовать совместно с другими объектами синхронизации ядра. Содержанием объекта мьютекс является идентификатор захватившего его процесса и счетчик рекурсии. Мьютекс находится в свободном состоянии, если он не захвачен никаким потоком. При успешном вызове Wait-функции на мьютексе в нем записывается идентификатор процесса, и объект переходит в занятое состояние. Другие потоки не смогут захватить его до тех пор, пока он не будет освобожден. Счетчик рекурсии будет использоваться в том случае, если мьютекс повторно попытается захватить тот же процесс – при этом доступ к объекту будет получен, а значение счетчика рекурсии увеличено. Если один поток захватывает мьютекс несколько раз, то и освободить он его должен такое же число раз. Для использования мьютекса его необходимо создать с помощью функции CreateMutex: HANDLE CreateMutex( LPSECURITY_ATTRIBUTES lpMutexAttributes, // SD BOOLbInitialOwner, // initial owner LPCTSTR lpName // object name ); При создании мьютекса мы можем сразу захватить его, передав в параметре bInitialOwner значение TRUE. Открыть существующий мьютекс по имени может функция OpenMutex. Для работы с мьютексом нам необходимы две операции – захват и освобождение. Захват мьютекса является побочным эффектом Wait-функций, и никакой специальной функции для этого не предусмотрено. Освобождается мьютекс с помощью функции ReleaseMutex: BOOL ReleaseMutex( HANDLE hMutex // handle to mutex ); Освободить мьютекс с помощью этой функции может только тот поток, который является владельцем мьютекса в данный момент. При этом, если этот поток захватывал мьютекс несколько раз, то и освобождать он его должен такое же число раз, только после этого доступ к объекту смогут получить другие объекты. Интересная ситуация возникает если поток, захвативший мьютекс прекращает свое существование, не освободив объект. В этом случае Windows автоматически освобождает мьютекс. Если в это время этот объект ждут другие потоки, то один из них сможет захватить его. Однако Wait-функция этого потока вернет не значение WAIT_OBJECT_0 а значение WAIT_ABADONED, информируя, что отказ от мьютекса произошел некорректно.
|