Монитор операционной системы — специальный модуль в составе операционной системы, решающий задачу предоставления ресурсов процессам. Все процессы обращаются к монитору за ресурсами, которые они предполагают использовать. Наличие монитора позволяет централизовать процесс распределения ресурсов и учет их использования.
Рис. 1.  
На входе в монитор решается задача взаимоисключения. Только один процесс может попасть в монитор в данный момент времени.
Пусть вычислительная система располагает различными ресурсами, доступ к которым организован через монитор. В общем случае, за использование каждого ресурса в мониторе отвечает своя процедура, к которой и обращается процесс, желающий получить доступ к данному ресурсу (рис. 2).
Рис. 2.  
Пусть процесс претендует на использование ресурса . обращается к соответствующей процедуре Procedure L. При таком обращении возможны два варианта.
Вариант 1. Ресурс занят другим процессом и не может быть предоставлен процессу . В этом случае Procedure L сообщает процессу, что ресурс занят. Процесс выводится из монитора и помещается в список-очередь процессов, ожидающих предоставления ресурса . Для каждого ресурса монитор поддерживает такой список-очередь (рис. 3).
Рис. 3.  
При этом, конечно, сам процесс никуда не перемещается, в список заносится лишь его идентификатор. Процесс переводится монитором в состояние блокировки (ожидания).
В этом варианте сама процедура выполняет единственное действие: сообщает процессу о занятости ресурса. Вывод процесса из монитора, занесение его в список ожидающих и изменение его состояния выполняет глобальная процедура монитора
Wait (condition)
Condition — переменная, значение которой определяется тем, к какому ресурсу пытался получить доступ процесс . В соответствии с этим значением процедура Wait заносит процесс в ту или иную очередь.
Таким образом, процедура Wait выполняет следующие действия:
  1. Вывод процесса из монитора.
  2. Занесение идентификатора процесса в список процессов, ожидающих ресурса .
  3. Перевод процесса в состояние блокировки (ожидания).
Вариант 2. Ресурс свободен и может быть предоставлен процессу. В этом случае процедура помечает ресурс как занятый и процесс выводится из монитора, получая ресурс в свое распоряжение (рис. 4).
Рис. 4.  
Завершив использование ресурса, процесс снова пытается войти в монитор для того, чтобы освободить ресурс. При этом он обращается к той же самой процедуре . Очевидно, процедура должна иметь параметр, определяющий, собирается ли процесс захватывать или освобождать ресурс.
Процедура помечает ресурс как свободный и вызывает глобальную процедуру монитора
Signal (condition)
Процедура Signal выполняет следующие действия:
  1. Выводит процесс из монитора.
  2. Если очередь на получение данного ресурса не пуста, из нее, в соответствии с определенными правилами и приоритетами выбирается один из процессов и переводится в состояние готовности, получая при этом в свое распоряжения запрашиваемый ресурс. Ресурс помечается как занятый (рис. 5).
Рис. 5.  
Рассмотрим пример простейшего монитора, осуществляющего распределение ресурсов.
Program Monitor1;
var Res_free : condition;
    Res_busy : boolean;

Procedure Get_Res;
begin
  If Res_busy then Wait(Res_free);
  Res_busy:=True;
end;

Procedure Put_Res;
begin
  Res_busy:=False;
  Signal(condition);
end;

begin
  Res_busy:=False;
end.
Монитор работает в полном соответствии с описанной нами выше логикой. Данный простейший пример монитора обеспечивает доступ к одному ресурсу. Соответственно, имеются две процедуры: для запроса ресурса (Get_Res) и для освобождения ресурса (Put_Res). Глобальная процедура Res_busy фиксирует текущее состояние ресурса (занят или свободен), переменная Res_free является идентификатором ресурса, используемым в глобальных процедурах Wait и Signal для помещения процесса в соответствующую очередь ожидания ресурса (сами глобальные процедуры в нашем примере не рассматриваются).
Для захвата ресурса процесс вызывает процедуру Get_Res. Происходит проверка свободности ресурса, если он свободен — помечается как занятый и процесс выводится их монитора, получая ресурс в свое распоряжение. Если ресурс занят, вызывается глобальная процедура Wait, помещающая ресурс в очередь и переводящая его в состояние блокировки. Процесс, переведенный в состояние блокировки "засыпает" на выполнении процедуры Wait.
Для освобождения ресурса процесс вызывает процедуру Put_Res. Ресурс помечается как свободный, вызывается процедура Signal для опроса очереди ожидающих процессов и возможного перевода одного из них в состояние готовности.