Для понимания основных причин возникновения тупиков рассмотрим несколько простых характерных примеров.
Пример тупика на ресурсах типа cr
Пусть имеются три процесса ПР1, ПР2 и ПРЗ, которые вырабатывают соответственно сообщения Ml,M2 и МЗ. Эти сообщения представляют собой ресурсы типа CR. Пусть процесс ПР1 является «потребителем» сообщения МЗ, процесс ПР2 получает сообщение Ml, а ПРЗ – сообщение М2 от процесса ПР2, то есть каждый из процессов является и «поставщиком» и «потребителем» одновременно, и вместе они образуют «кольцевую» систему (рис. 9.2) передачи сообщений через почтовые ящики (ПЯ). Если связь с помощью этих сообщений со стороны каждого процесса устанавливается в порядке, изображенном в листинге 9.1, то никаких трудностей не возникает. Однако перестановка этих двух процедур в каждом из процессов (листинг 9.2) вызывает тупик:
Рис. 9.2. Кольцевая схема взаимодействия процессов
Листинг 9.1. Вариант без тупиковой ситуации
ПР1:...
ПОСЛАТЬ СООБЩЕНИЕ (ПР2, M1, ПЯ2);
|
|
ЖДАТЬ СООБЩЕНИЕ (ПР3, М3, ПЯ1);
...
ПР2:...
ПОСЛАТЬ СООБЩЕНИЕ (ПРЗ, М2, ПЯ3);
ЖДАТЬ СООБЩЕНИЕ (ПР1, M1, ПЯ2);
...
ПРЗ:...
ПОСЛАТЬ СООБЩЕНИЕ (ПР1, МЗ, ПЯ1);
ЖДАТЬ СООБЩЕНИЕ (ПР2, М2, ПЯ3);
...
Листинг 9.2. Вариант с тупиковой ситуацией
ПР1:...
ЖДАТЬ СООБЩЕНИЕ (ПР3, М3, ПЯ1);
ПОСЛАТЬ СООБЩЕНИЕ (ПР2, M1, ПЯ2);
...
ПР2:...
ЖДАТЬ СООБЩЕНИЕ (ПР1, M1, ПЯ2);
ПОСЛАТЬ СООБЩЕНИЕ (ПРЗ, М2, ПЯЗ);
...
ПРЗ:...
ЖДАТЬ СООБЩЕНИЕ (ПР2, М2, ПЯЗ);
ПОСЛАТЬ СООБЩЕНИЕ (ПР1, МЗ, ПЯ1);
...
В самом деле, во втором варианте ни один из процессов не сможет послать сообщения до тех пор, пока сам его не получит, а этого события никогда не произойдет, поскольку ни один процесс не может этого сделать.