Реализация мониторов с помощью семафоров
В предыдущем разделе было описано, как реализовать мониторы с помощью ядра. Здесь показано, как реализовать их, используя семафоры. Это может понадобиться по двум прими-
Глава 6. Реализация 227
нам: 1) библиотека программирования поддерживает семафоры и не поддерживает мониторы, или 2) язык программирования обеспечивает семафоры и не обеспечивает мониторы. Так или иначе, описываемое решение иллюстрирует еще одно применение семафоров.
Вновь используем семантику мониторов, определенную в разделе 5.1. Следовательно, нужно реализовать взаимное исключение процедур монитора и условную синхронизацию между ними. В частности, нужно разработать: 1) код входа, который выполняется после вызова процедуры монитора из процесса, но перед началом выполнения тела процедуры; 2) код выхода, выполняемый перед выходом процесса из тела процедуры; 3) код, реализующий операции wait, signal и другие операции с условными переменными. Для простоты предположим, что есть только одна условная переменная; разработанный ниже код несложно обобщить на случай нескольких условных переменных, используя массивы очередей задержки и счетчиков.
Для реализации исключения в мониторах используем по одному входному семафору на монитор. Пусть е — семафор, связанный с монитором М. Поскольку семафор е должен использоваться для получения взаимного исключения, он инициализируется значением 1, и его значение всегда должно быть или 0 или 1. Цель протокола входа каждой процедуры монитора М — обеспечить исключительный доступ к м. Как всегда, для этого используется операция Р (е). Аналогично протокол выхода каждой процедуры снимает блокировку монитора, поэтому реализуется операцией V (е).
Выполнение операции wait(cv) снимает блокировку монитора и задерживает выполняемый процесс на условной переменной cv. Процесс продолжает работу в мониторе после получения сигнала и нового исключительного доступа к монитору.