на начало
На главную страницу
Форум   

Статья :: COMPEBOOK.RU - Компьютерные электронные книги, электронные учебники

 

Мьютексы (Mutexes)

Критические секции просты в использовании и обладают высоким быстродействием, но не обладают гибкостью в управлении. Нет, например, возможности установить время блокирования или присвоить имя критической секции для того, чтобы два разных процесса могли иметь с ней дело. Оба эти недостатка можно устранить, если использовать такой объект ядра, как mutex. Термин mutex происходит от mutually exclusive (взаимно исключающий). Этот объект обеспечивает исключительный (exclusive) доступ к охраняемому блоку кодов. Например, если несколько процессов должны одновременно работать с одним и тем же связным списком, то на время выполнения каждой операции: добавления, удаления элемента или сортировки, следует заблокировать список и разрешить доступ к нему только одному из процессов.

Для синхронизации потоков разных процессов следует объявить один общедоступный объект класса CMutex, который будет управлять доступом к списку. Мыо-текс предоставляет доступ к объекту любому из потоков, если в данный момент объект не занят, и запоминает текущее состояние объекта. Если объект занят, то мьютекс запрещает доступ. Однако можно подождать освобождения объекта с помощью функции WaitForSingleObject, в которой роль управляющего объекта выполняет тот же мьютекс. Типичная тактика использования такова. Объект

CMutex mutex;

необходимо объявить заранее. Обычно он является членом thread-safe-класса. В точке, где необходимо защитить код, создается объект класса CSingleLock, которому передается ссылка на мьютекс. При попытке включения блокировки вызовом метода Lock надо в качестве параметра указать время (в миллисекундах), в течение которого следует ждать освобождения объекта, охраняемого мьютексом. В течение этого времени либо получим доступ к объекту, либо не получим его. Если объект стал доступен, то мы запираем его от других потоков и производим работу, которая требует синхронизации. После этого освобождаем блокировку. Если время ожидания истекло и доступ к объекту не получен, то обработка этой ситуации (ветвь else) целиком в нашей власти. Если задать ноль в качестве параметра функции Lock, то ожидания не будет. Напротив, можно ждать неопределенно долго, если передать константу INFINITE.

Другой процесс, если он знает, что существует мьютекс с каким-то именем, может сделать этот объект доступным для себя, открыв уже существующий мьютекс. При вызове функции OpenMutex система сканирует существующие объекты-мьютексы, проверяя, нет ли среди них объекта с указанным именем. Обнаружив таковой, она создает описатель объекта, специфичный для данного процесса. Теперь любой поток данного процесса может использовать описатель в целях синхронизации доступа к какому-то коду или объекту. Когда мьютекс становится ненужным, следует освободить его вызовом

CloseHandle(HANDLE hObject);

где hObject — описатель мьютекса. Когда система создает мьютекс, она присваивает ему имя (строка в стиле С). Это имя используется при совместном доступе к мыотексу нескольких процессов. Если несколько потоков создают объект с одним и тем же именем, то только первый вызов приводит к созданию мьютекса. Имя используется при совместном доступе нескольких процессов. Если оно совпадает с именем уже существующего объекта, конструктор создает новый экземпляр класса CMutex, который ссылается на существующий мьютекс с данным именем. Если имя не задано (IpszName равен NULL) мьютекс будет неименованным, и им можно пользоваться только в пределах одного процесса.

С любым объектом ядра сопоставляется счетчик, фиксирующий, сколько раз данный объект передавался во владение потокам. Если поток вызовет, например, CSingleLock: :Lock() ИЛИ WaitForSingleObject () ДЛЯ уже принадлежащего ему объекта, он сразу же получит доступ к защищаемым этим объектом данным, так как система определит, что поток уже владеет этим объектом. При этом счетчик числа пользователей объекта увеличится на 1. Теперь, чтобы перевести объект в свободное состояние, потоку необходимо соответствующее число раз вызвать CSingleLock::Unlock() ffilHReleaseMutex() . Функции EnterCriticalSection и LeaveCriticalSection действуют по отношению к критическим секциям аналогичным образом.

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

 

CompEbook.ru Железо, дизайн, обучение и другие

COMPEBOOK.RU - Компьютерные электронные книги, электронные учебники

страницы в данном разделе 
Урок 12 Некоторые сведения об архитектуре Windows
Windows 2000 — многозадачная операционная система Уровни и платформы
Однозадачные операционные системы Многозадачные операционные системы
Процессы и потоки Приоритеты процессов
Приоритеты потоков Переключение потоков
Архитектура памяти Win32 Разделы адресного пространства
Подсистемы ОС Взаимодействие подсистем
Разделяемые ресурсы Стратегии решения проблемы
Транзакции Тупиковая ситуация (Deadlock)
Механизмы синхронизации Критические секции
COMPEBOOK.RU - Компьютерные электронные книги, электронные учебники События
Семафоры Блокировки (Locks)
Специальные блокировки Устранение тупиковых ситуаций


Содержание сайта (выборка)
Apache
Протоколы TCP/IP (принципы, протоколы и архитектура)



PHP, PELR, JSP
PHP
JavaServer Pages (JSP)

Базы данных
Основы mysql
СУБД INFORMIX
СУБД POSTGRES
Основы проектирования реляционных баз данных

HTML, javascript
Спецификация HTML 4.01
Каскадные Таблицы Стилей, Уровень 2
Клиентский JavaScript. Справочник.
JavaScript руководство пользователя
Серверный JavaScript 1.4. Руководство по Использованию.

Паскаль, C, C++, C#
GCC (примеры)
FAQ Валентинa Озеровa DELPHI
C



 
© faq.pp.ru, справочник программиста