Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Учебное пособие 700363.doc
Скачиваний:
16
Добавлен:
01.05.2022
Размер:
3.69 Mб
Скачать

Алгоритм 3

В этом алгоритме предпринята попытка устранить недостаток второго алгоритма и позволить процессам входить в критическую секцию в произвольном порядке.

// подготовка – любой процесс // может войти в критическую секцию extern bool flag_1 = false, flag_2 = false;

// процесс 1 // цикл ожидания while(flag_2); // захват // критической секции flag_1 = true; // код // критической секции // освобождение // критической секции flag_1 = false;

// процесс 2 // цикл ожидания while(flag_1); // захват // критической секции flag_2 = true; // код // критической секции // освобождение // критической секции flag_2 = false;

Однако, при детальном рассмотрении легко заметить, что данный алгоритм не обеспечивает взаимоисключения по той же причине, что и алгоритм 1. Действительно, если процесс будет снят с исполнения после проверки, но до установки флага, то взаимоисключение может быть нарушено.

Алгоритм 4

Алгоритм 3 может быть незначительно модифицирован, чтобы гарантировать взаимоисключение.

// подготовка – любой процесс // может войти в критическую секцию extern bool flag_1 = false, flag_2 = false;

// процесс 1 // намерение // процесса 1 войти в // критическую секцию flag_1 = true; // цикл ожидания while(flag_2); // код // критической секции // освобождение // критической секции flag_1 = false;

// процесс 2 // намерение // процесса 2 войти в // критическую секцию flag_2 = true; // цикл ожидания while(flag_1); // код // критической секции // освобождение // критической секции flag_2 = false;

В данном алгоритме нарушение взаимоисключения невозможно, зато возможна взаимная блокировка процессов. Действительно, если, процесс 1 установит свой флаг и будет снят с выполнения до проверки флага второго процесса в цикле ожидания, а процесс 2, начав исполнение, установит свой флаг, то оба процесса будут бесконечно выполнять цикл ожидания, и ни один из них не войдет в критическую секцию.

Алгоритм 5

Для исключения взаимной блокировки, возможной в алгоритме 4, необходимо, чтобы процесс, находящийся в цикле ожидания, время от времени сбрасывал бы свой флаг хотя бы на непродолжительное время, чтобы дать возможность второму процессу возможность разорвать взаимную блокировку и войти в критическую секцию.

Усовершенствованный алгоритм может быть следующим.

// подготовка – любой процесс // может войти в критическую секцию extern bool flag_1 = false, flag_2 = false;

// процесс 1 // намерение // процесса 1 войти в // критическую секцию flag_1 = true; // цикл ожидания while(flag_2) { // предоставить шанс // для процесса 2 войти // в критическую секцию flag_1 = false; delay(rand());

flag_1 = true; } // код // критической секции // освобождение // критической секции flag_1 = false;

// процесс 2 // намерение // процесса 2 войти в // критическую секцию flag_2 = true; // цикл ожидания while(flag_1) { // предоставить шанс // для процесса 1 войти // в критическую секцию flag_2 = false; delay(rand());

flag_2 = true; } // код // критической секции // освобождение // критической секции flag_2 = false;

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

Таким образом, алгоритм 5 способен обеспечить взаимоисключения при доступе к критическим ресурсам, но при потенциально возможном длительном откладывании.