ЛЕКЦИЯ 4 СИНХРОНИЗАЦИЯ ПРОЦЕССОВ
ВОПРОСЫ 1. Синхронизация процессов с использованием объектов ядра. 2. Задачи синхронизации. 3. Мониторы Хоара. 4. Почтовые ящики. 5. Конвейеры и очереди сообщений.
Литература 1. Системное программное обеспечение /А.В. Гордеев, А.Ю. Молчанов. – СПб.: Питер – с. 236…259.
function WaitForSingleObject (hHandle: THandle; dwMilliseconds: DWORD): DWORD; stdcall; Задаваемые значения
WAIT_OBJECT_0 - объект находится в состоянии «свободно»; WAIT_TIMEOUT - интервал ожидания, заданный dwMilliseconds, истек, а нужный объект по прежнему находится в состоянии «занято»; WAIT_ABANDONED относится только к мьютексу и означает, что объект не был освобожден потоком, который владел им до своего завершения; WAIT_FAILED - при выполнении функции произошла ошибка. Возвращаемые значения
Объект ядра мьютекс (mutex) (mutual exclusion semaphore) CreateMutex - создание OpenMutex - открытие WaitForSingleObjects - ожидание WaitForMultipleObjects - событий ReleaseMutex – освобождение объекта CloseHandle() – закрытие мьютекса Функции мьютексов
function CreateMutex(lpMutexAttributes: PSecurityAttributes; bInitialOwner: BOOL; lpName: PChar): THandle;
События HANDLE CreateEvent( ** ) LPSECURITY_ATTRIBUTES IpEventAttributes, // Указатель на атрибуты защиты BOOL bManualReset, // Флаг интерактивного события. BOOL bInitialState, // Флаг первоначального состояния. LPCTSTR IpName // Указатель на имя события
Функция OpenEvent HANDLE OpenEvent( DWORD dwDesiredAccess, // Флаг доступа BOOL blnheritHandle, // Флаг наследования LPCTSTR IpName // Указатель на имя события );
Параметр dwDesiredAccess EVENT_ALL_ACCESS предоставляет полный доступ к событию; EVENT_MODIFY_STATE разрешает использование дескриптора события в функциях SetEvent и ResetEvent (вызывающий процесс может изменить состояние данного объекта); SYNCHRONIZE разрешает использование дескриптора события в любых функциях ожидания (таких как WaitForSingleObject), ждущих освобождения данного объекта.
Семафоры function CreateSemaphore (SemaphoreAttributes: PSecurityAttributes; IInitialCount, iMaximumCount: Longint; IpName: PChar): THandle; stdcall;
Семафоры SemaphoreAttributes – атрибуты защиты ; IInitialCount – начальное значение счетчика (0…. iMaximumCount); iMaximumCount – максимальное значение счетчика семафора; IpName – имя семафора. CloseHandle() – закрытие семафора
Семафоры Function ReleaseSemaphore (hSemaphore: THanddle ; IReleaseCount: Longint ; IpPreviousCount: Pointer ): BOOL; stdcall
Ждущие таймер CancelWaitableTimer Останавливает работу. СгеаteWaitableTimer Создает (открывает) объект ждущего таймера. OpenWaitableTimer Открывает существующий ждущий таймер. SetWaitableTimer Запускает ждущий таймер с заданной продолжительностью и интервалом срабатывания
Режимы работы ждущего таймера 1. Ручного сброса; 2. Автоматического сброса; 3. Интервального.
2. Задачи синхронизации Производитель - потребитель Читатели – писатели Обедающие философы
Задача «производитель – потребитель» Var S_свободно, S_заполнено, S_взаимоискл: semaphore; begin InitSem(S_свободно,N); InitSem(S_заполнено,0); InitSem(S_взаимоискл,1); parbegin Производитель: while true do begin …{приготовить сообщение} P(S_свободно); P(S_взаимоискл); … {послать сообщение } V(S_заполнено); V(S_взаимоискл); end; and
(продолжение) ПОТРЕБИТЕЛЬ : while true do begin P(S_заполнено); P(S_взаимоискл); … {получить сообщение} V(S_свободно); V(S_взаимоискл); … {обработать сообщение} end parend end.
Задача «читатели – писатели» с приоритетом «читателей» var R, W : semaphore; NR : integer; procedure ЧИТАТЕЛЬ; begin P(R); Inc(NR); { NR:=NR +1 } if NR = 1 then P(W); V(R); Read_Data; { критический интервал } P(R); Dec(NR); if NR = 0 then V(W); V(R) end;
(продолжение) procedure ПИСАТЕЛЬ; begin P(W); Write_Data; { критический интервал } V(W) end begin NR: =0; InitSem(S,1); InitSem(W,1); parbegin while true do ЧИТАТЕЛЬ and while true do ЧИТАТЕЛЬ and
(продолжение)... while true do ЧИТАТЕЛЬ and while true do ПИСАТЕЛЬ and while true do ПИСАТЕЛЬ and... while true do ПИСАТЕЛЬ parend end.
Мониторы Хоара Пример monitor Resourse; condition free; { условие – свободный } var busy : boolean; {busy - занят} procedure REQUEST; {запрос} begin if busy then WAIT ( free ); busy:=true; Take0ff; { ВЫДАТЬ РЕСУРС} end
(продолжение) procedure RELEASE; begin Take0n; {ВЗЯТЬ РЕСУРС} busy:=false; SIGNAL(free); {деблокирует процесс, находящийся в начале очереди} end; begin busy:=false; end.
Почтовые ящики SEND_MESSAGE – переписывает сообщение в буфер, помещает его адрес в переменную буфер к очереди получатель WAIT_MESSAGE – получает имя отправителя в переменной отправитель, текст сообщения – в сообщение и адрес буфера – в буфер. SEND_ANSWER – записывает ответ в тот буфер, из которого было получено сообщение и добавляет буфер к очереди отправителя. WAIT_ANSWER – блокирует процесс, выдавший операцию, до тех пор, пока в буфер не поступит ответ.
Конвейеры Функции DosCreatePipe – создание конвейера; DosRead – чтения из конвейера; DosWrite – записи в конвейер.
Организация очереди на массиве
Очереди сообщений CreateQueue – создание новой очереди OpenQueue - открытие существующей очереди ReadQueue – чтение и удаление сообщения PeekQueue - чтение сообщения без его последующего удаления из очереди WriteQueue - добавление сообщения в очередь CloseQueue - завершение использования очереди PurgeQueue удаление из очереди всех сообщений QueryQueue определение числа элементов в очереди
Схема взаимодействия параллельно выполняющихся задач