ВУЗ:
Составители:
• Мьютекс (MUTual Exclusions – взаимоисключения) – это объект ядра, который можно использовать для синхро-
низации потоков из разных процессов. Он может принадлежать или не принадлежать некоторому потоку. Если мьютекс
принадлежит потоку, то он находится в состоянии "занято". Если данный объект не относится ни к одному потоку, то он на-
ходится в состоянии "свободно". Другими словами, принадлежать для него означает быть в состоянии "занято".
Если мьютекс не принадлежит ни одному потоку, первый поток, который вызовет функцию WaitForSingleObject, завла-
девает данным объектом, и тот переходит в состояние "занято". В определенном смысле мьютекс похож на выключатель,
которым может пользоваться любой поток по принципу "первым пришел – первым обслужили" (first-come-first,-served).
Дело в том, что при попытке с помощью вызова функции WaitForSingleObject завладеть мьютексом, который уже нахо-
дится в состоянии "занято", поток переводится в состояние ожидания до того момента, когда данный объект освободится,
т.е. когда "владелец" мьютекса его освободит (переведет в состояние "свободно").
По принципу своего действия мьютексы очень похожи на критические секции, за исключением двух моментов: во-
первых, мьютексы можно использовать для синхронизации потоков, переступая через границы процессов; во-вторых, мью-
тексу можно присвоить имя и путем ссылки на это имя создать дополнительные дескрипторы существующих объектов мью-
тексов.
Мьютексы создаются с помощью вызова функции CreateMutex:
HANDLE CreateMutexi
LPSECURITY_ATTRIBUTES // Указатель на атрибуты защиты.
IpMutexAttributes,
BOOL bInitialOwner, // Флаг первоначального владельца.
LPCTSTR IpName // Указатель на имя мьютекса.
);
Параметр IpMutexAttributes – это указатель на запись типа TSecurityftttributes. Обычно в качестве данного параметра
передастся значение nil, и в этом случае используются атрибуты защиты, действующие по умолчанию.
Параметр blnitialOwner определяет, следует ли считать поток, создающий мьютекс, его владельцем. Если этот параметр
равен False, значит, мьютекс не имеет владельца.
Параметр IpName представляет имя мьютекса. Если нет необходимости присваивать мьютексу имя, следует установить
этот параметр равным nil. Если же значение этого параметра отлично от nil, функция выполнит в системе поиск мьютекса с
таким же именем. При успешном завершении поиска функция вернет дескриптор найденного мьютекса, в противном случае
возвращается дескриптор нового мьютекса. При наличии имени этот объект может совместно использоваться несколькими
процессами. Если каким-то процессом создается мьютекс с именем, то поток другого процесса может вызывать функции
CreateMutex или OpenMutex с тем же самым именем. В любом случае система просто передаст вызывающему потоку деск-
риптор исходного мьютекса. Другой способ совместно использовать мьютекс – вызвать функцию DuplicateHandle.
Чтобы работать с несколькими процессами, данный объект должен быть совместно используемым. Причина проста:
чтобы завладеть мьютексом или освободить его, потоку потребуется его дескриптор. Поток освобождает этот объект с по-
мощью вызова функции ReleaseMutex:
BOOL ReleaseMutex(
HANDLE hMutex // Дескриптор мьютекса.
);
А что случится, если владеющий мьютексом поток завершится, предварительно не освободив его? В действительности
система сама освобождает такой мьютекс. Поток, который вызывает функцию WaitForSingleObject для этого объекта, получит
возвращенное значение WAIT_ABANDONED, которое указывает на возникшие проблемы с только что завершимся пото-
ком-владельцем. В этом случае ждущий поток должен определить, стоит продолжать выполнение в обычном режиме или
нет.
По завершении использования мьютекса необходимо закрыть его с помощью функции Win32 API CloseHandle().
• События используются в качестве сигналов о завершении какой-либо операции. Однако в отличие от мьютексов
они не принадлежат ни одному потоку. Например, поток А создает событие с помощью функции CreateEvent и устанавлива-
ет объект в состояние "занято". Поток В получает дескриптор этого объекта, вызвав функцию OpenEvent, затем вызывает
функцию WaitForSingleObject, чтобы
приостановить работу до того момента, когда поток А завершит конкретную задачу и
освободит указанный объект. Когда это произойдет, система выведет из состояния ожидания поток В, который теперь владе-
ет информацией, что поток А завершил выполнение своей задачи.
Объявление функции CreateEvent записывается таким образом:
HANDLE CreateEvent(
LPSECURITY_ATTRIBUTES // Указатель на атрибуты защиты.
IpEventAttributes,
BOOL bManualReset, // Флаг интерактивного события.
BOOL bInitialState, // Флаг первоначального состояния.
LPCTSTR IpName // Указатель на имя события.
);
Функция возвращает дескриптор создаваемого объекта "событие". Первый параметр определяет, наследуется ли деск-
риптор порожденными процессами. Если IpEventAttributes имеет значение NULL, дескриптор наследоваться не может.
Если параметр bManualReset имеет значение TRUE, то при освобождении объект остается в этом состоянии (в отличие
от объекта "мъютекс"). Это значит, что все потоки, ожидающие перехода данного объекта в состояние "свободно", будут
выведены системой из состояния ожидания. Такой объект называется событием с ручным сбросом (manual-reset event), по-
скольку "разбуженный" (выведенный из состояния ожидания) поток может самостоятельно сбросить состояние объекта "со-
бытие" в "занято". Если параметр bManualReset имеет значение FALSE, то система автоматически сбрасывает состояние рас-
Страницы
- « первая
- ‹ предыдущая
- …
- 28
- 29
- 30
- 31
- 32
- …
- следующая ›
- последняя »