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

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

Рис. 2.4.  Реализация критических секций с использованием блокирующих переменных

Другим средством является использования блокирующих переменных. С каждым что разделяется ресурсом связывается двоичная переменная, что принимает значение 1, если ресурс свободный (то есть никакой процесс не находится в данный момент в критической секции, связанной с данным процессом), и значение 0, если ресурс занят. На рисунке 2.4 показанный фрагмент алгоритма процесса, который использует для реализации взаимного исключения доступа к что разделяется ресурса D блокирующую переменную F(D). Перед входом в критическую секцию процесс проверяет, свободный ли ресурс D. Если он занят, то проверка циклически повторяется, если свободный, то значение переменной F(D) устанавливается в 0, и процесс входит в критическую секцию. После того, как процесс выполнит все действия с что разделяется ресурсом D, значение переменной F(D) снова устанавливается равным 1.

Если все процессы написаны с использованием вышеописанных соглашений, то взаимное исключение гарантируется. Следует заметить, что операция проверки и установки блокирующей переменной должна быть неделимой. Объясним это. Пусть в результате проверки переменной процесс определил, что ресурс свободный, но сразу после этого, не устигнувши установить переменную в 0, был прерванный. За время его прекращения другой процесс занял ресурс, вошел в свою критическую секцию, но также был прерванный, не завершивши работы по что разделяется ресурсом. Когда управление было возвращено первому процессу, он, считая ресурс свободным, установил признак занятости и начал выполнять свою критическую секцию. Таким образом был затронутый принцип взаимного исключения, которое потенциально может привести к нежелает следствиям. Во избежание таких ситуаций в системе команд машины желательно иметь единую команду " проверка-установка", или же реализовывать системными средствами соответствующие программные примитивы, которые бы запрещали прерывание на протяжении всей операции проверки и установки.

Реализация критических секций с использованием блокирующих переменных имеет существенный недостаток: на протяжении времени, когда один процесс находится в критической секции, другой процесс, которому нужно тот же ресурс, будет выполнять рутинные действия по опитуваннню блокирующей переменной, напрасно тратя процессорное время. Для устранения таких ситуаций может быть использованный так называемый аппарат событий. С помощью это средства могут решаться не только проблемы взаимного исключения, но и более общие задачи синхронизации процессов. В разных операционных системах аппарат событий реализуется по своему, но в любом случае используются системные функции аналогичного назначения, которые условно назовем WAIT(x) и POST(x), где x - идентификатор некоторого события. На рисунке 2.5 показанный фрагмент алгоритма процесса, который использует эти функции. Если ресурс занят, то процесс не выполняет циклическое опрашивание, а вызывает системную функцию WAIT(D), здесь D обозначает событие, которое состоит в освобождении ресурса D. Функция WAIT(D) перекладывает активный процесс в состояние ОЖИДАНИЯ и делает оценку в его дескрипторе о том, что процесс ожидает событию D. Процесс, который в это время использует ресурс D, после выхода из критической секции выполняет системную функцию POST(D), в результате чего операционная система просматривает очередь процессов , которые ожидают , и перекладывает процесс, который ожидает событию D, в состояние ГОТОВНОСТЬ.

 

Возможно стоит прочитать: