
- •1.Операционные системы.
- •2 . Архитектура ос.
- •4. Страничная организация виртуальной памяти.
- •5. Стратегии вытеснения страниц
- •6. Совместный доступ к памяти
- •7. Основы api Win32. Примеры.
- •8.Вытесняющая многозадачность, планирование.
- •10. Создание потоков (нитей, threads) и управление потоками.
- •11. Классы для работы с потоками
- •12. Синхронизация потоков. Критические секции
- •В начале критической секции необходимо вызвать подпрограмму api
- •13. Объекты синхронизации и функции ожидания
- •Wait-функции
- •14. Семафоры, мьютексы, события
- •Семафор создается функцией
- •InitialCount: longint; // Начальное число потоков, // допущенных к объекту
- •4.4. События (Event)
Семафор создается функцией
function CreateSemaphore (
Attr: Pointer; // указатель на атрибуты безопасности
InitialCount: longint; // Начальное число потоков, // допущенных к объекту
MaxCount: longint; // Максимальное число допускаемых // потоков
lpName: PChar // имя семафора
): THandle; // дескриптор семафора
Семафор сигнализирует, если InitialCount больше нуля, и не подает сигнала, если InitialCount равен нулю.
Для доступа к объекту используется функция ожидания WaitForSingleObject или WaitForMultipleObjects.
При завершении функции ожидания значение счетчика InitialCount соответственно уменьшается, и поток получает доступ к ресурсу.
При завершении доступа к ресурсу необходимо вызвать функцию, увеличивающую значение счетчика семафора:
function ReleaseSemaphore(
hHandle: THandle; // дескриптор мьютекса
ReleaseCount: longint // приращение счетчика
LP: Pointer // как правило, nil
): Boolean;
4.4. События (Event)
Данные объекты синхронизации используются обычно не для доступа к данным, а для того, чтобы оповестить другие потоки о том, что некоторое действие завершено. Пусть, например, в некотором приложении один поток читает данные из файла в буфер памяти, а другие потоки их обрабатывают. В начале работы первый поток устанавливает объект «Cобытие» в несигнальное состояние. Остальные потоки выполнили вызов функции ожидания и находятся в приостановленном состоянии, ожидая наступления события. Как только буфер заполняется, первый поток сообщает об этом ОС, вызывая сигнализацию события, ОС активизирует потоки.
Переключение события из сигнального состояния в несигнальное может происходить вручную и автоматически. В первом случае событие переключается явным вызовом функции ResetEvent. Во втором переключение в несигнальное состояние производится операционной системой, когда один из ожидающих событие потоков завершается.
Для создания объекта «Событие» используется функция:
function CreateEvent( lpEventAttributes: PSecurityAttributes; //адрес //структуры атрибутов безопасности bManualReset, //определяет, будет ли событие отключаемым //вручную (TRUE) или автоматически (FALSE) bInitialState: BOOL; // задает начальное состояние (если // TRUE то событие сигнализирует) lpName: PChar // имя или NIL, если имя не требуется ):Thandle; stdcall; // возвращает дескриптор события
Параметр lpName позволяет разделять объекты между процессами. Как и в случае с мьютексами, если lpName совпадает с именем уже существующего объекта типа Event, созданного текущим или любым другим процессом, функция не создает нового объекта, а возвращает идентификатор уже существующего. При этом игнорируются параметры bManualReset, bInitialState и lpSecurityDescriptor.
Если объект используется для синхронизации внутри одного процесса, его можно объявить как глобальную переменную и создавать без имени. Имя объекта не должно совпадать с именем любого из существующих объектов синхронизации.
Если известно, что Event уже создан, для получения доступа к нему можно вместо CreateEvent воспользоваться функцией:
function OpenEvent( dwDesiredAccess: DWORD; // Задает права доступа к объекту bInheritHandle: BOOL; // Задает, может ли объект // наследоваться дочерними процессами lpName: PChar // Имя объекта ): THandle; stdcall;
Функция возвращает дескриптор (идентификатор объекта), либо 0, в случае ошибки. Параметр dwDesiredAccess может принимать одно из следующих значений:
EVENT_ALL_ACCESS |
Приложение получает полный доступ к объекту |
EVENT_MODIFY_STATE |
Приложение может изменять состояние объекта функциями SetEvent и ResetEvent |
SYNCHRONIZE |
Только для Windows NT/2k/XP – приложение может использовать объект только в функциях ожидания |
После получения идентификатора можно приступать к его использованию. Функция
function SetEvent(hEvent: THandle): BOOL; stdcall;
устанавливает объект в сигнальное состояние.
Функция
function ResetEvent(hEvent: THandle): BOOL; stdcall;
сбрасывает объект, устанавливая его в несигнальное состояние.
Функция
function PulseEvent(hEvent: THandle): BOOL; stdcall
устанавливает объект в сигнальное состояние, дает отработать всем функциям ожидания, ожидающим этот объект, а затем снова сбрасывает его.
По завершении работы с объектом, он должен быть уничтожен функцией CloseHandle. Примеры использования событий приведены в статье [3].