Средства высокого уровня
Рассмотренных до сих пор средств достаточно, чтобы обеспечить правильное исполнение параллельных процессов.
Однако их использование сильно напоминает программирование на языке ассемблера с командами загрузки, сложения и условного перехода. Насколько удобней писать на языке программирования, в котором есть операторы присваивания, выражения и средства структурирования программы. Точно так же пользователю для создания параллельных процессов гораздо удобнее пользоваться операциями высокого уровня, и такие операции, по-видимому, будут играть все возрастающую роль в программных системах. Реализация этих операций требует использования примитивных операций низкого уровня, таких как Р и V. Хотя определение и использование эких операций, строго говоря, относится к проблемам создания языков программирования, тем не менее здесь уместно кратко остановиться на двух из них.
Средства, предлагаемые до сих пор, приостанавливали процесс до тех пор, пока не выполнится определенное условие. Критические интервалы приостанавливали процесс до освобождения совместно используемого ресурса; семафоры - до получения синхронизирующего сигнала; почтовые ящики - до поступления сообщения. Условный критический интервал - это программная конструкция, которая представляет программисту средства для синхронизации процесса а основе выполнения произвольного условия.
Это условие связано с разделяемой переменной условного критического интервала. При входе в условный критический интервал процесс сначала проверяет эту переменную, чтобы определить, не выполнено ли соответствующее условие. Если да, он продолжает свою работу. Если нет, он ждет в очереди событий. связанной с данным критическим интервалом. Всякий раз, когда процесс покидает критический интервал, существует вероятность того, что он изменил разделяемую переменную, связанную с условием. Поэтому в этот момент времени все процессы из очереди событий переводятся в очередь готовых к исполнению процессов, и после установки на процессор они могут снова войти в критический интервал снова проверить условие. Таким образом, возможность использования произвольного условия для синхронизации получена за счет контролируемого числа проверок, выполняемых взаимодействующими процессами. При этом по-прежнему исключается активная форма ожидания.
Условные переменные являются более мощным средством, чем семафоры, так как семафор может только подсчитывать количество свершений некоторого события. Для каждого события (например, запись записана, запись прочитана), которое влияет на условие синхронизации, требуется отдельный семафор, а при использовании условных критических интервалов можно обойтись одной переменной. Более того, для тех, кто читает программу, эта переменная может быть намного понятнее, чем взаимоотношения между несколькими семафорами.
Другой конструкцией высокого уровня является монитор (или “секретарь”). Использование слова “монитор” в данном контексте очень специфично, и его не следует путать с более общим использованием этого термина в таком выражении, как “монитор работ”. В параллельном программировании монитор - это пассивный набор разделяемых переменных и повторно входимых процедур доступа к ним. Процесс, желающий получить доступ к разделяемым переменным, должен
Рис.2.21. Монитор для выделения одного ресурса.
обратиться к монитору, который либо предоставит доступ, либо откажет в нем. Чтобы предоставить доступ, монитор выполняет процедуру, соответствующую обращению, которая может иметь параметры. При отказе монитор блокирует обратившийся процесс и определяет условие, по которому процесс ждет. Проверка условия выполняется не самим обратившимся процессом, как это было в случае условных критических интервалов, а монитором, который также деблокирует ожидающий процесс.
На рис. 2.21 предложен простой пример. Единственный ресурс динамически запрашивается и освобождается процессами, которые обращаются к процедурам ЗАПРЕС и ОСВОБОДИТЬ. Если процесс обращается к ЗАПРЕС в тот момент, когда ресурс используется, значение переменной занят будет true и ЗАПРЕС выполнит операцию монитора ЖДАТЬ (свободный). Эта операция, блокирует не процедуру ЗАПРЕС, а обратившийся процесс. Этот процесс помещается в конец очереди процессов, ожидающих, пока не будет выполнено условие свободный. Когда процесс, использующий ресурс, обращается к процедуре ОСВОБОДИТЬ, операция монитора СВЕРШИТЬ деблокирует процесс, находящийся в начале очереди, не позволяя исполняться никакой другой процедуре внутри того же монитора. Этот процесс готов возобновить исполнение ЗАПРЕС сразу же после операции ЖДАТЬ. Если СВЕРШИТЬ выполняется в то время, когда нет процесса, ожидающего условия, то никакие действия не выполняются.
Существенным ограничением является тот факт, что только одному процессу в данный момент разрешено выполнять любые процедуры монитора. Разделяемые ресурсы доступны только через монитор. Следовательно, монитор заменяет критический интервал для реализации взаимного исключения. Монитор пассивен в том смысле, что это не процесс; его процедуры выполняются только по требованию процесса. Можно также считать, что монитор является защитной оболочкой, которая ограждает критический ресурс и средства доступа к нему. Если процедуры одним и тем же образом используют разделяемую переменную, применяя для этого семафоры, то каждому семафору потребуется своя собственная копия одного и того же критического интервала При использовании вместо этого монитора достаточно одной встроенной в него копии.