Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
kt.doc
Скачиваний:
9
Добавлен:
26.09.2019
Размер:
590.34 Кб
Скачать

30.Семафоры Дейкстры

Понятие семафоров было введено Дейкстрой. Семафор S – это переменная специального типа, дос-тупная параллельным процессам для проведения над ней только двух неделимых операций: закрытия P(S) и открытия V(S). Поскольку эти операции неделимы, то они исключают друг друга. Семафорный механизм работает по следующей схеме: вначале исследуется состояние критического ресурса, определяемое значением семафора. В зависимости от результата про-исходит или предоставление ресурса или ожидание доступа в очереди в режиме “пассивного ожидания”. В состав механизма включаются специальные средства формирования и обслуживания очереди ожидающих процессов ОС. В силу неделимости операций, даже если некоторые процессы одновременно захотят использовать критический ресурс, доступ получит только один, а второй будет помещен в очередь. Процессам из очереди не предоставляется процессорное время, пока ресурс занят. Допустимыми значениями семафоров являются целые числа. Семафор называется двоичным, если максимальное значение, которое он может принять, это 1. Если больше, то семафор – N-ричный. Рассмотрим пример реализации. Допустим, семафор S инициализируется ОС в значение 1. Тогда операции P и V имеют вид:

void P (int *S)

{(*S)--; // закрытие семафора и доступа

if (*S<0) block_process();} // если семафор уже был закрыт, поместить в очередь блокировки

void V (int *S)

{if (*S<0) activate_process(); // если есть очередь блокировки, поставить процесс на готовность

(*S)++;} // открыть семафор

Сами процессы будут иметь вид:

void process(void)

{while(1)

{P(&S); //установка семафора

critical_section(); //или операция успешна или процесс взят из очереди

V(&S); //восстановление семафора

non_critical_section();}}

Пусть оба процесса пытаются выполнить P(S), и это успешно удается второму процессу. Он устанавливает семафор в 0 и переходит к выполнению КС. Тем временем процесс 1 пытается выполнить P(S). Он устанавливает семафор в –1, и помеща-ется ОС в очередь ожидания. Процесс 2 выполняет КС, и вызывает V(S). Поскольку семафор<0, т.е. есть очередь, то процесс 1 выводится из очереди и переходит к выполнению КС. Тем временем процесс 2 восстанавливает значение семафора до 0. В итоге противоречий нет: семафор закрыт, в очереди нет процессов.

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

Одним из вариантов организации работы с семафором являются мьютексы mutex (mutual exclusion – взаимное исключе-ние). Реализованы во многих ОС, представляют собой простейшие двоичные семафоры, которые могут находиться только в одном из двух состояний – открыт или закрыт. Соответственно для реализации требуется всего 1 бит, хотя обычно исполь-зуют переменную типа int, у которой 0 – открытое состояние, 1 – закрытое. Значение мьютекса устанавливается 2 процеду-рами. Если процесс хочет войти в КС, он вызывает процедуру закрытия мьютекса, например mutex_lock. Если мьютекс от-крыт, то запрос выполняется и вызывающий процесс может попасть в КС. Если же мьютекс закрыт, то процесс блокируется, пока другой процесс, находящийся в КО, не выйдет из нее, открыв мьютекс соответствующей процедурой, например, mutex_unlock. Как только какой-либо процесс становится владельцем объекта mutex, он закрывается, а когда задача его ос-вобождает, он открывается. Пример реализации мьютекса:

mutex_lock:

bts mutex, 1 ; закрыть мьютекс

jnc OK ; если мьютекс был открыт, то конец процедуры

call thread_yield ;иначе поток блокируется, передается управление другому

jmp mutex_lock ;новая попытка

OK: ret;

mutex_unlock:

move mutex, 0 ;открыть мьютекс

ret;

От прямого использования операции TS имеется одно существенное отличие: не используется активного ожидания. Сущест-вует еще одна проблема, связанная с синхронизацией, про которую не было сказано. В рассмотренных ранее случаях (алго-ритмы Деккера и Петерсона, семафоры) предполагалось, что имеется общая глобальная переменная. Однако процессы име-ют каждый свое адресное пространство. Как организовать доступ к общему участку памяти? Существует 2 варианта реше-ния. 1: совместно используемые переменные, например, семафоры, хранить в ядре с доступом через системные запросы. 2: позволить процессам использовать некоторую общую область памяти. Как правило, в современных ОС реализованы оба ва-рианта.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]