Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ОС СФМЭИ.doc
Скачиваний:
22
Добавлен:
17.09.2019
Размер:
1.37 Mб
Скачать

7.2.4. Синхронизация с использованием процессов и потоков

Процессы и потоки можно использовать и для решения задач синхронизации.

Объект ядра «процесс» сразу после создания всегда находятся в занятом состоянии. В момент завершения процесса операционная система автоматически освобождает его объект ядра «процесс», и он навсегда остается в свободном состоянии.

Точно такие же правила распространяются и на объекты ядра «поток». Они тоже сразу после создания находятся в занятом состоянии. Когда поток завершается, операционная система автоматически переводит объект ядра «поток» в свободное состояние. Как и объект ядра «процесс», объект ядра «поток» никогда не возвращается в занятое состояние.

7.2.5. Объекты Mutex

Объекты ядра Mutex (мьютекс) гарантируют потокам взаимоисключающий доступ к единственному ресурсу. Мьютексы ведут себя точно так же, как и критические секции. Однако, если последние являются объектами пользовательского режима, то мьютексы — объекты ядра. Кроме того, объект Mutex позволяет синхронизировать доступ к ресурсу нескольких потоков из разных процессов; при этом можно задать максимальное время ожидания доступа к ресурсу.

Для использования объекта Mutex один из процессов должен сначала создать его вызовом CreateMutex:

function CreateMutex(lpMutexAttributes: PSecurityAttributes;

bInitialOwner: Boolean; lpName: PChar): THandle;

где lpMutexAttributes – указывает на структуру SECURITY_ATTRIBUTES, которая содержит информацию о защите объекта ядра «mutex». Если защиты не нужно в этот параметр заносится nil.

bInitialOwner – определяет начальное состояние мьютекса. Если в нем передается FALSE (что обычно и бывает), объект-мьютекс не принадлежит ни одному из потоков и поэтому находится в свободном состоянии. Если же в нем передается TRUE, мьютекс изначально находится в занятом состоянии.

lpName – указатель на сроку, , заканчивающуюся двоичным нулем и содержащую имя объекта «mutex». Применяется в тех случаях, когда объект «mutex» используется для синхронизации потоков разных процессов. Если мьютекс используется для синхронизации потоков одного процесса, этот параметр устанавливается в nil.

При успешном выполнении функция CreateMutex возвращает дескриптор мьютекса, В случае ошибки функция возвращает nil. Причем, если при вызове функции CreateMutex указывается имя мьютекса и объект мьютекс с таким именем уже существует, то функция вернет значение – nil, а функция GetLastError вернет значение - ERROR_ALREADY_EXISTS.

Любой процесс может получить свой («процессно-зависимый») дескриптор существующего объекта "мьютекс", вызвав функцию OpenMutex:

function OpenMutex(dwDesiredAccess: DWORD; bInheritHandle: Boolean;

lpName: PChar): THandle;

где dwDesiredAccess - определяет требуемый доступ к мьютексу. Возможные значения данного параметра приведены в таблице 7.1.

bInheritHandle - определяет тип наследования дескриптора. Если данный параметр имеет значение TRUE, процесс, создаваемый функцией CreateProcess, будет наследовать данный дескриптор. Если же параметр имеет значение FALSE, дескриптор мьютекса не будет наследуемым.

lpName - указатель на сроку, заканчивающуюся двоичным нулем и содержащую имя мьютекса.

Таблица 7.1 Значения параметра dwDesiredAccess

Значение

Описание

MUTEX_ALL_ACCESS

Означает все возможные флаги доступа для мьютекса

SYNCHRONIZE

Допускается использование дескриптора объекта мьютекс в любой wait- функции для ожидания освобождения мьютекса

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

Если Wait-функция определяет, что мьютекс занят, то поток переходит в состояние ожидания освобождения объекта мьютекс.

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

function ReleaseMutex(hMutex: THandle): Boolean;

где hMutex – дескриптор объекта мьютекс.

При успешном выполнении функция ReleaseMutex возвращает значение TRUE.

Объект мьютекс отличается от остальных объектов ядра тем, что занявшему его потоку передаются права на владение им. Объекты мьютексы способны запоминать, какому потоку они принадлежат. Если какой-то посторонний поток попытается освободить мьютекс вызовом функции ReleaseMutex, то данная функция вернет FALSE. Вызов функции GetLastError даст значение ERROR_NOT_OWNER.