Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Языки программирования. Практический сравнитель...doc
Скачиваний:
33
Добавлен:
09.09.2019
Размер:
2.68 Mб
Скачать

12.4. Мониторы и защищенные переменные

Проблема, связанная с семафорами и аналогичными средствами, обеспечи­ваемыми операционной системой, состоит в том, что они не структурны. Ес­ли нарушено соответствие между Wait и Signal, программа может утратить синхронизацию или блокировку. Для решения проблемы структурности была разработана концепция так называемых мониторов (monitors), и они реализованы в нескольких языках. Монитор — это совокупность данных и подпрограмм, которые обладают следующими свойствами:

• Данные доступны только подпрограммам монитора.

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

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

Первоначально модель параллелизма в языке Ada (описанная ниже в раз­деле 12.7) была чрезвычайно сложной и требовала слишком больших затрат для решения простых проблем взаимных исключений. Чтобы это исправить, в Ada 95 были введены средства, аналогичные мониторам, которые называ­ются защищенными переменными (protected variables). Например, семафор можно смоделировать как защищенную переменную. Этот интерфейс опре­деляет две операции, но целочисленное значение семафора рассматривает как приватное (private), что означает, что оно недоступно для пользователей семафора:

protected type Semaphore is

entry Wait;

procedure Signal;

private

Value: Integer := 1;

end Semaphore;

Реализация семафора выглядит следующим образом:

protected body Semaphore is

entry Wait when Value > 0 is

begin

Ada

Value := Value- 1;

end Wait;

procedure Signal is

begin

Value := Value + 1 ;

end Signal;

end Semaphore;

Выполнение entry и procedure взаимно исключено: в любой момент времени только одна задача будет выполнять операцию с защищенной переменной. К тому же entry имеет барьер (barrier), который является булевым выражением. Задача, пытающаяся выполнить entry, будет заблокирована, если выражение имеет значение «ложь». Всякий раз при завершении защищенной операции все барьеры будут перевычисляться, и будет разрешено выполнение той зада­чи, барьер которой имеет значение «истина». В приведенном примере, когда Signal увеличит Value, барьер в Wait будет иметь значение «истина», и забло­кированная задача сможет выполнить тело entry.

12.5. Передача сообщений

По мере того как компьютерные аппаратные средства дешевеют, распреде­ленное программирование приобретает все большее значение. Программы раз­биваются на параллельные компоненты, которые выполняются на разных компьютерах. Модель с разделяемой памятью уже не годится; проблема син­хронизации и связи переносится на синхронную передачу сообщений (syn­chronous message passing), изображенную на рис. 12.2. В этой модели канал связи с может существовать между любыми двумя процессами. Когда один процесс посылает сообщение m в канал, он приостанавливается до тех пор, пока другой процесс не будет готов его получить. Симметрично, процесс, ко­торый ожидает получения сообщения, приостанавливается, пока посылаю­щий процесс не готов послать. Эта приостановка используется для синхро­низации процессов.

Синхронная модель параллелизма может быть реализована в самом языке программирования или в виде услуги операционной системы: потоки (pipes),

гнезда (sockets) и т.д. Модели отличаются способами, которыми процессы адресуют друг друга, и способом передачи сообщений. Далее мы опишем три языка, в которых методы реализации синхронного параллелизма сущест­венно различны.