Студопедия.Орг Главная | Случайная страница | Контакты | Мы поможем в написании вашей работы!  
 

Монитор



Метода Сергеева:

Определение 2.7 Монитор - это набор процедур, переменных и других структур данных, объединенных в особый модуль или пакет.

Замечание 2.6 Процессы могут вызывать процедуры монитора, но у процедур, объявленных вне монитора, нет прямого доступа к внутренним структурам данных мониторов.

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

Для блокировки процессов вводятся переменные состояния и две операции (wait, signal). Когда процедура монитора обнаруживает, что она не в состоянии продолжить работу, она выполняет операцию wait на какой-либо переменной состояния (full). Это приведет к блокировке вызывающего процесса и позволяет другому процессу войти в монитор.

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

- запускать „разбуженный“ процесс и останавливать второй (Хоар);

- процесс, выполнивший signal, должен немедленно покинуть монитор (Хансен);

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

Замечание 2.7 Операция wait должна выполняться прежде, чем signal.

Недостатки мониторов:

- отсутствие языка программирования со встроенными мониторами;

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

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

Таненбаум:

Чтобы упростить написание программ, Бринч Хансен (Brinch Hansen) в 1973 году и Хоар (Ноаге) в 1974 году предложили примитив синхронизации более высокого уровня, называемый монитором.

Монитор — это набор процедур, переменных и других структур данных, объединенных в особый модуль, или пакет. Процессы могут вызывать процедуры монитора, но у процедур, объявленных вне монитора, нет прямого доступа к внутренним структурам данных монитора.

В листинге 2.6 представлен монитор, написанный на воображаемом языке, некоем «местечковом диалекте» — «пиджин» Pascal.

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

Листинг 2.6. Монитор

monitor example

integer i;

condition с;

procedure producer(x);

….

end;

procedure consumer(x);

end;

end monitor;

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

Хотя мониторы предоставляют простой механизм реализации взаимного исключения, этого недостаточно. Необходим также способ блокировки процессов, которые не могут продолжать свою деятельность. В случае проблемы производителя и потребителя достаточно просто поместить все проверки буфера (пуст — не пуст) в процедуры монитора, но как процесс заблокируется, обнаружив полный буфер?

Решение заключается в условных переменных и двух операциях, wait и signal. Когда процедура монитора обнаруживает, что она не в состоянии продолжать работу (например, производитель выясняет, что буфер заполнен), она выполняет операцию wait для какой-либо условной переменной, скажем, full. Это приводит к блокировке вызывающего процесса и позволяет другому процессу войти в монитор.

Другой процесс, потребитель может активизировать ожидающего напарника, например, выполнив операцию signal для той условной переменной, для которой он был заблокирован. Чтобы в мониторе не оказалось двух активных процессов одновременно, нам необходимо правило, определяющее последствия операции signal. Xoap предложил запуск «разбуженного» процесса и остановку второго. Бринч Хансен придумал другое решение: процесс, выполнивший операцию signal, должен немедленно покинуть монитор. Иными словами, операция signal выполняется только в самом конце процедуры монитора.

Если операция signal выполнена для переменной, с которой связаны несколько заблокированных процессов, планировщик выбирает и «оживляет» только один из них.

Кроме этого, существует третье решение, не основывающееся на предположениях Хоара и Хансена: позволить процессу, выполнившему операцию signal, продолжать работу и запустить ожидающий процесс только после того, как первый процесс покинет монитор. Операция wait должна выполняться прежде, чем signal.

В листинге 2.7 представлена схема решения проблемы производителя и потребителя с применением мониторов, написанная на языке «пиджин» Pascal. В каждый момент времени активна только одна процедура монитора. Буфер состоит из N сегментов.

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

Листинг 2.7. Схема решения проблемы производителя и потребителя с применением мониторов

monitor ProducerConsumer

condition full, empty;

integer count;

procedure insert(item: integer);

begin

if count = N then wait(full);

insert_item(item);

count:= count+1;

if count = 1 then signal(empty)

end;

function remove: integer;

begin

if count = 0 then wait(empty);

remove = remove_item;

count:= count—1;

if count = N-l then signal(full)

end;

count:= 0;

end monitor;

procedure producer;

begin

while true do

begin

item = produce_item;

ProducerConsumer.insert(item)

end

end;

procedure consumer;

begin

while true do

begin

item = ProducerConsumer.remove;

consume_item(item)

end

end;

У мониторов есть свои недостатки. Недаром монитор, представленный в листинге 2.7, написан на «пиджин» Pascal, а не на С, как все остальные примеры этой книги. Как мы уже говорили, мониторы являются структурным компонентом языка программирования, и компилятор должен их распознавать и организовывать взаимное исключение. Языки Pascal, С и многие другие не поддерживают мониторов.

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





Дата публикования: 2015-01-26; Прочитано: 801 | Нарушение авторского права страницы | Мы поможем в написании вашей работы!



studopedia.org - Студопедия.Орг - 2014-2024 год. Студопедия не является автором материалов, которые размещены. Но предоставляет возможность бесплатного использования (0.007 с)...