Простой пример - 4


Пусть сначала процесс 1 обнаружит, что "c2 = 1".

Пусть процесс 2 немедленно вслед за этим проверяет значение cl; тогда он еще найдет, что "cl = 1". Каждый из процессов, удостоверившись, что другой не находится в критическом интервале, решит, что он может безопасно войти в свой собственный критический интервал!

Мы должны действовать более осторожно. Давайте поменяем местами в самом начале процессов проверку чужого "с" и установку собственного "с". Получаем такую программу:

begin integer cA, c2; cl := 1; c2 := 1; parbegin

процесс 1: begin Al : cl := 0; L1 : if c2 = 0 then goto L1; критический интервал 1; cl := 1; остаток цикла 1; goto Al end; процесс 2: begin A2 : c2 := 0; L2 : if cl = 0 then goto L2; критический интервал 2; c2 := 1; остаток цикла 2; goto A2 end; parend; end

Имеет смысл убедиться в том, что это решение во всяком случае совершенно безопасно. Давайте сосредоточим внимание на моменте, когда процесс 1 обнаруживает, что "c2 = 1", и поэтому решает войти в свой критический интервал. В этот момент мы можем заключить:

  1. соотношение "cl = 0" уже установлено и будет сохраняться, пока процесс 1 не завершит выполнение своего критического интервала;
  2. так как "c2 = 1", то процесс 2 находится вне критического интервала, в который он не может войти, пока сохраняется "cl = 0", т. е. пока процесс 1 еще пребывает в своем критическом интервале.

Итак, взаимное исключение действительно гарантировано.

Но, увы, это решение также должно быть отвергнуто: предпринятые в нем меры безопасности слишком сильны, так что оно содержит опасность взаимной блокировки. Если после присваивания "cl := 0", но еще до проверки c2 (и то, и другое в процессе 1), процесс 2 выполнит присваивание "c2 := 0", то это значит, что оба процесса достигли соответственно меток L1 и L2 и одновременно справедливы соотношения "cl = 0" и "c2 = 0". В итоге процессы будут безрезультатно ждать друг от друга разрешения войти в критический интервал.




Начало  Назад  Вперед