Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Итог / +Раздел VIII. Операционные системы.doc
Скачиваний:
99
Добавлен:
23.03.2015
Размер:
278.53 Кб
Скачать

43. Синхронизация процессов: условия корректной синхронизации; алгоритмы с активным ожиданием; примитивы межпроцессорного взаимодействия: семафоры, сообщения, мониторы.

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

Основным способом предотвращения проблем при совместном использовании ресурсов является запрет одновременного доступа к разделяемым данным более чем одного процесса, называемый взаимным исключением.

Часть программы, в которой есть обращение к совместно используемым данным,

назовем критической областью.

Для правильной совместной работы взаимодействующих процессов необходимо

выполнение следующих условий:

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

  2. Два или более процессов не могут одновременно находиться в своих критических областях, относящихся к одним и тем же разделяемым данным. Условие взаимного исключения.

  3. Процесс, находящийся вне критической области, и не стремящийся попасть в критическую область не может блокировать другие процессы. Только процессы стремящиеся попасть в критическую область учитываются при определении очередности доступа. Условие прогресса.

  4. Невозможна ситуация, в которой процесс вечно ждет попадания в критическую область. Условие ограниченного ожидания.

Для решения задачи взаимного исключения необходимо, чтобы когда некоторый процесс находится в своем критическом участке, другие процессы не могли войти в свои критические участки (блокироваться). Поэтому каждый процесс при входе в критическую область выполняет действия, обеспечивающие монопольное использование данных и приводящие к блокировке других процессов (пролог). А при выходе соответственно выполняются действия, деблокирующие другие процессы (эпилог).Во время выполнения пролога процесс должен, в частности, получить разрешение на вход в критическую область, а во время выполнения эпилога – сообщить другим процессам, что он покинул критическую область.

Алгоритмы с активным ожиданием.

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

Постоянная проверка переменной в ожидании требуемого значения называется активным ожиданием. Активное ожидание используется только в случае, когда существует уверенность в небольшом времени ожидания.

  1. Переменные блокировки. Алгоритм основан на использовании разделяемой переменной, значение которой используется для блокировки процессов.

2) Строгое чередование. Алгоритм основан на использовании переменной, которая не только используется для блокировки, но и указывает, какой процесс может войти в критическую область.

3)Флаги готовности. Недостаток предыдущего алгоритма заключается в том, что процессы не имеют информации о состоянии друг друга в текущий момент времени.

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

4)Алгоритм Петерсона. Для корректного решения проблемы требуется доступ обоих процессов доступ к массиву флагов готовности и к переменной очередности, что используется в алгоритме Петерсона (1981 г.). Если оба процесса подошли к прологу практически одновременно, то они оба объявят о своей готовности и предложат выполняться друг другу. При этом одно из предложений всегда последует после другого. Тем самым работу в критическом участке продолжит процесс, которому было сделано последнее предложение.

  1. Алгоритм булочной.

Алгоритм Петерсона дает решение задачи корректной организации взаимодействия двух процессов. Рассмотрим соответствующий алгоритм для n взаимодействующих процессов, который получил название алгоритм булочной.

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

Примитивы межпроцессорного взаимодействия.

Оба решения корректны, но они обладают общим недостатком – использованием активного ожидания. Активное ожидание не только бесцельно расходует время процессора, но может иметь более серьезные последствия. Рассмотрим, например, два процесса: Н, с высоким приоритетом, и L, с низким приоритетом. Процесс Н запускается немедленно, как только он оказывается в состоянии готовности.

Пусть в момент, когда процесс L находится в критической области, процесс Н находится в состоянии готовности и пытается попасть в критическую область. В результате процесс Н попадает в состояние активного ожидания, но поскольку процессу L во время работающего процесса Н никогда не будет предоставлено процессорное время, у процесса L не будет возможности выйти из критической области, и процесс Н навсегда останется в цикле. Эту ситуацию иногда называют проблемой инверсии приоритета.

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

Семафор представляет собой целую переменную, принимающую неотрицательные значения, доступ к которой любого процесса, за исключением момента ее инициализации, может осуществляться только через две атомарные операции: Down и Up. Классическое определение этих операций выглядит следующим образом: Таким образом, при выполнении операции Down над семафором S сначала проверяется его текущее значение. Если оно больше 0, то из S вычитается 1. Если оно меньше или равно 0, то процесс блокируется до тех пор, пока S не станет больше 0, после чего из S вычитается 1. При выполнении операции Up над семафором S к его значению просто прибавляется 1.

Все операции проверки значения семафора, его изменения и перевода процесса в

состояние ожидания выполняются как атомарное действие. Тем самым гарантируется, что после начала операции ни один процесс не получит доступа к семафору до ее окончания.

Мониторы представляют собой тип данных, который может быть реализован в рамках концепции объектно-ориентированного программирования. Монитор обладает собственными переменными, определяющими его состояние.

Значения этих переменных могут быть изменены только с помощью вызова методов, принадлежащих монитору. В свою очередь, эти методы могут использовать в своей работе только данные, находящиеся внутри монитора и свои параметры. На абстрактном уровне можно описать структуру монитора следующим образом:

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

Для того чтобы в мониторе не оказалось двух процессов, разбудившего и пробужденного, будем предполагать, что разбудивший процесс покидает монитор немедленно после исполнения операции signal.

Для прямой и непрямой адресации достаточно двух примитивов, чтобы описать передачу сообщений по линии связи — send и receive. В случае прямой адресации примитивы имеют следующий формат:

send(P, message)—послать сообщение message процессу P;

receive(Q, message) — получить сообщение message от процесса Q.

В случае непрямой адресации вместо P и Q указывается идентификатор.

Примитивы send и receive уже имеют скрытый механизм взаимоисключения. Более того, в большинстве систем они уже имеют и скрытый механизм блокировки при чтении из пустого буфера и при записи в полностью заполненный буфер. Надо отметить, что, несмотря на простоту использования, передача сообщений в пределах одного компьютера происходит существенно медленнее, чем работа с семафорами и мониторами.