Все содержимое и примеры здесь взяты из
Операционные системы: внутреннее оборудование и принципы проектирования
Уильям Сталлингс
8º Edition
тупик: Ситуация, в которой два или более процесса не могут продолжаться, потому что каждый ожидает, что один другой сделает что-то.
Например, рассмотрим два процесса, P1 и P2, и два ресурса, R1и R2.Предположим, что каждому процессу необходим доступ к обоим ресурсам для выполнения части его функций.Тогда возможна следующая ситуация: ОС назначает R1 для P2 и R2 для P1.Каждый процесс ожидает один из двух ресурсов.Ни один из них не освободит ресурс, которым он уже владеет, пока он не получит другой ресурс и не выполнит функцию, требующую оба ресурса.Два процесса заблокированы
Livelock : Ситуация, в которой два или более процессов непрерывно изменяют свои состояния в ответ на изменения в других процессах без какой-либо полезной работы:
Голодание : Ситуация, когда планировщик игнорирует запущенный процесс;хотя он может продолжаться, он никогда не выбирается.
Предположим, что каждому из трех процессов (P1, P2, P3) требуется периодический доступ к ресурсу R. Рассмотрим ситуацию, в которой ресурс P1 находится во владении ресурса,и P2, и P3 задерживаются, ожидая этого ресурса.Когда P1 выходит из своей критической секции, P2 или P3 должен быть разрешен доступ к R. Предположим, что ОС предоставляет доступ к P3 и что P1 снова требует доступа до того, как P3 завершит свою критическую секцию.Если ОС предоставляет доступ к P1 после завершения P3 и впоследствии поочередно предоставляет доступ к P1 и P3, то P2 может быть бесконечно отказано в доступе к ресурсу, даже если нет тупиковой ситуации.
ПРИЛОЖЕНИЕ A - ТЕМЫ В СОВРЕМЕННОСТИ
Пример взаимоблокировки
Если оба процесса устанавливают свои флаги в true до того, как любой из них выполнил оператор while, тогда каждый будетдругой вошел в критическую секцию, вызывая взаимоблокировку.
/* PROCESS 0 */
flag[0] = true;
while (flag[1])
/* do nothing */;
/* critical section*/;
flag[0] = false;
/* PROCESS 1 */
flag[1] = true;
while (flag[0])
/* do nothing */;
/* critical section*/;
flag[1] = false;
Пример Livelock
/* PROCESS 0 */
flag[0] = true;
while (flag[1]){
flag[0] = false;
/*delay */;
flag[0] = true;
}
/*critical section*/;
flag[0] = false;
/* PROCESS 1 */
flag[1] = true;
while (flag[0]) {
flag[1] = false;
/*delay */;
flag[1] = true;
}
/* critical section*/;
flag[1] = false;
[...] рассмотрим следующую последовательность событий:
- P0 устанавливает флаг [0] в true.
- P1 устанавливает флаг [1] в true.
- P0 проверяет флаг [1].
- P1 проверяет флаг [0].
- P0 устанавливает флаг [0] в значение false.
- P1 устанавливает флаг [1] в значение false.
- P0 устанавливает флаг [0]в true.
- P1 устанавливает флаг [1] в true.
Эта последовательность может быть расширена до бесконечности, и ни один из процессов не можетЯ войду в его критическую секцию.Строго говоря, это , а не тупик , потому что любое изменение относительной скорости двух процессов нарушит этот цикл и позволит одному войти в критическую секцию.Это условие называется livelock .Напомним, что тупик возникает, когда набор процессов хочет войти в свои критические секции, но ни один процесс не может быть успешным.С livelock возможны последовательности выполнений, которые успешны, но также возможно описать одну или несколько последовательностей выполнения, в которых ни один процесс никогда не входит в свою критическую секцию.