Студопедия.Орг Главная | Случайная страница | Контакты | Мы поможем в написании вашей работы!  
 

События с автоматическим сбросом



Освобождаются с помощью SetEvent(…), переходят в занятое состояние с помощью WaitForMultipleObjects(…), как только событие освобождается.

WaitForMultipleObjects(…);

.

.

.

SetEvent(…);

Для событий с автосбросом SetEvent(…) не используется.

23. Объекты Мutex.

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

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

function CreateMutex(lpMutexAttributes: PSecurityAttributes;

bInitialOwner: BOOL; lpName: PChar): THandle;

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

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

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

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

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

HANDLE OpenMutex(DWORD fdwAccess, 800L bInheritHandle, PCTSTR pszName);

function OpenMutex(dwDesiredAccess: DWORD; bInheritHandle: BOOL;

lpName: PChar): THandle;

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

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

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

Значения параметра dwDesiredAccess

Значение Описание
MUTEX_ALL_ACCESS Означает все возможные флаги доступа для мьютекса
SYNCHRONIZE Допускается использование дескриптора объекта мьютекс в любой wait- функции для ожидания освобождения мьютекс.

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

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

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

function ReleaseMutex(hMutex: THandle): BOOL;

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

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

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

24. Синхронизация потоков с помощью семафоров.

Объекты ядра «семафор» используются для учета ресурсов Как и все объекты ядра, они содержат счетчик числа пользователей, но, кроме того, поддерживают два 32 битных значения со знаком: одно определяет максимальное число ресурсов (контролируемое семафором), другое используется как счетчик текущего числа ресурсов

Для семафоров определены следующие правила:

· когда счетчик текущего числа ресурсов становится больше 0, семафор переходит в свободное состояние,

· если этот счетчик равен 0, семафор занят,

· система не допускает присвоения отрицательных значений счетчику текущего числа ресурсов;

· счетчик текущего числа ресурсов не может быть больше максимального числа ресурсов

Не следует путать счетчик текущего числа ресурсов со счетчиком числа пользователей объекта-семафора

Объект ядра «семафор» создается вызовом функции CreateSemapbore: function CreateSemaphore(lpSemaphoreAttributes: PSecurityAttributes;

lInitialCount, lMaximumCount: Longint; lpName: PChar): THandle;

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

lInitialCount – счетчик текущего числа ресурсов.

lMaximumCount – максимальное число ресурсов, контролируемое семафором. Данный параметр должен быть больше 0.

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

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

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

function OpenSemaphore(dwDesiredAccess: DWORD; bInheritHandle: BOOL;

lpName: PChar): THandle;

где dwDesiredAccess - определяет требуемый доступ к объекту «семафор». Возможные значения данного параметра приведены в таблице 7.2.

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

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

Значения параметра dwDesiredAccess

Значение Описание
SEMAPHORE_ALL_ACCESS Означает все возможные флаги доступа для объекта «семафор»
SEMAPHORE _MODIFY_STATE Объект событие можно использовать только в функции ReleaseSemaphore для изменения счетчика текущего числа ресурсов
SYNCHRONIZE Допускается использование дескриптора объекта «семафор» в любой wait- функции для ожидания освобождения семафора.

Поток получает доступ к ресурсу, вызывая одну из Wait-функций и передавая ей дескриптор семафора. Wait-функция проверяет у семафора счетчик текущего числа ресурсов, если его значение больше 0 (семафор свободен), уменьшает значение этого счетчика на 1, и вызывающий поток остается планируемым

Если Wait - функция определяет, что счетчик текущего числа ресурсов равен 0 (семафор занят), система переводит вызывающий поток в состояние ожидания. Когда другой поток увеличит значение этого счетчика, система вспомнит о ждущем потоке и снова начнет выделять ему процессорное время (а он, захватив ресурс, уменьшит значение счетчика на 1).

Поток увеличивает значение счетчика текущего числа ресурсов, вызывая функцию ReleaseSemaphore:

function ReleaseSemaphore(hSemaphore: THandle; lReleaseCount:

Longint;lpPreviousCount: Pointer): BOOL;

Где hSemaphore – дескриптор семафора.

Данная функция складывает величину lReleaseCount со значением счетчика текущего числа ресурсов. Обычно в параметре lReleaseCount передают 1, но это вовсе не обязательно. Функция возвращает исходное значение счетчика ресурсов в lpPreviousCount.Если исходное значение счетчика в приложении не используется, то вместо параметра lpPre viousCountзаписывается значение nil.

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

25. Синхронизация потоков с помощью событий. События со сбросом вручную и с автоматическим сбросом.

События уведомляют об окончании какой-либо операции. Объекты-события бывают двух типов: со сбросом вручную (manual-reset events) и с автосбросом (auto-reset events). Первые позволяют возобновлять выполнение сразу нескольких ждущих потоков, вторые — только одного.

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

Для работы с объектом «событие» используются следующие функции:

1. Создание объекта ядра «событие», функция CreateEvent:

function CreateEvent(lpEventAttributes: PSecurityAttributes;

bManualReset, bInitialState: BOOL; lpName: PChar): THandle;

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

Пареметр fManualReset (булева переменная) определяет тип объекта «событие» - событие со сбросом вручную (TRUE) или с автосбросом (FALSE).

Параметру fInitialState определяет начальное состояние события — свободное (TRUE) или занятое (FALSE).

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

После того как система создает объект событие, CreateEvent возвращает дескриптор события, специфичный для конкретного процесса. Потоки из других процессов могут получить доступ к этому объекту:

· вызовом CreateEvent с тем же параметром lpName;

· наследованием l;tcrhbgnjhf;

· применением функции DuplicateHandle;

· вызовом OpenEvent c передачей в параметре lpName имени, совпадающего с указанным в аналогичном параметре функции CreateEvent.

2. Открытие объекта ядра «событие», функция OpenEvent:

function OpenEvent(dwDesiredAccess: DWORD; bInheritHandle: BOOL; lpName: PChar): THandle;

где dwDesiredAccess - определяет требуемый доступ к объекту «событие».

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

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

Значения параметра dwDesiredAccess

Значение Описание
EVENT_ALL_ACCESS Означает все возможные флаги доступа для объекта «событие»
EVENT_MODIFY_STATE Объект событие можно использовать только в функциях SetEvent и ResetEvent для изменения состояния объекта «событие»
SYNCHRONIZE Допускается использование объекта «событие» в любой wait- функции для ожидания освобождения события.

3. Закрытие объекта ядра «событие».

Ненужный объект ядра "событие" следует закрыть вызовом CloseHandle.

4. Перевод события в свободное состояние

function SetEvent(hEvent: THandle): BOOL; где hEvent – дескриптор события.

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

5. Перевод события в занятое состояние

function ResetEvent(hEvent: THandle): BOOL; где hEvent – дескриптор события.

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





Дата публикования: 2014-11-03; Прочитано: 663 | Нарушение авторского права страницы | Мы поможем в написании вашей работы!



studopedia.org - Студопедия.Орг - 2014-2024 год. Студопедия не является автором материалов, которые размещены. Но предоставляет возможность бесплатного использования (0.01 с)...