| Каталог | Индекс раздела |
| Назад | Оглавление | Вперед |
Если мы доказали, что семафоры могут быть реализованы через мониторы, следующая задача должна показать, что и мониторы могут быть реализованы через семафоры.
Очевидно, что нам потребуется для каждого монитора булев семафор "mutex", чтобы гарантировать, что тела локальных процедур исключают друг друга. Семафор инициализирован значением 1; операция P(mutex) должна выполняться на входе в каждую локальную процедуру, и операция V(mutex) - на выходе из нее.
Когда процесс сигнализирует об условии, на котором другой процесс ожидает, сигнализирующий процесс должен ждать, пока восстановленный процесс разрешит ему продолжиться. Мы поэтому вводим для каждого монитора второй семафор "urgent" (инициализированный значением 0), на котором сигнализирующий процесс задерживается операцией P(urgent). Перед разрешением прерывания каждый процесс должен проверить, нет ли другого процесса, ожидающего на urgent, и, если так, должен освободить его вместо выполнения операции V(urgent). Мы поэтому должны подсчитывать число процессов, ожидающих на urgent, в целой переменной "urgentcount" (с начальным значением - 0). Так им образом, каждый выход из процедуры монитора должен кодироваться так:
if urgentcount > 0 then V(urgent) else V(mutex)
Наконец, для каждого условия, локального в мониторе, мы вводим семафор "condsem" (инициализированный значением 0), на котором процесс, желающий ждать, задерживается операцией P(condsem). Так как процесс, сигнализирующий об этом условии должен знать, ожидает ли на нем кто-либо, нам также нужно подсчитывать число ждущих процессов, в целой переменной "condcount" (первоначально - 0). Операция "cond.wait" может теперь быть реализована следующим образом (вспомните, что ожидающая программа должна разрешить прерывание перед приостановкой):
condocunt := condcount + 1; if urgentcount > 0 then V(urgent) else V(mutex); P(condsem); comment Здесь всегда будет ожидание; condcount := condcount - 1
Операция signal может быть представлена таким кодом:
urgentcount := urgentcount + 1;
if condcount > 0 then {V(condsem); P(urgent) };
urgentcount := urgentcount - 1;
В этой реализации, владение монитором представлено как привилегия, которая явно передается от одного процесса другому. Только, когда никто более не хочет претендует на эту привилегию, - mutex наконец освобождается.
Это решение не претендует на соответствие рекомендуемому "стилю" в использовании семафоров. Понятие переменной-условия введено как замена семафоров, и имеет собственный стиль использования, так же, как циклы с условием или сопрограммы предназначены как замены переходов. В многих случаях в универсальности этого решения нет необходимости, и возможны его значительные усовершенствования в смысле эффективности.
if condcount > 0 then V(condsem)
else if urgentcount > 0 then V(urgent)
else V(mutex)
Значительные усовершенствования в эффективности могут также быть получены исключением использования семафоров, и реализацией условия прямо на аппаратных средствах, или на самом низком и непрерываемом уровне программного обеспечения (т.е., в режиме супервизора). В этом случае возможны следующие оптимизации.
Я благодарен J. Bezivin, J. Horning, и R.M. McKeag для помощи в нахождении этого алгоритма.
| Назад | Оглавление | Вперед |
| Каталог | Индекс раздела |