Page 95 - 6571
P. 95

відвідувач з найменшим номером. Відмінність полягає в тому, що
            для визначення черговості обслуговування відвідувачі звіряються
            один з одним, а не із загальним лічильником.
                  Як  і  в  алгоритмі  квитка,  нехай  turn[1: n]  –  масив  цілих

            чисел  з  початковими  значеннями  0.  Щоб  увійти  в  критичну
            секцію,  процес  CS[i]  спочатку  присвоює  змінній  turn[i]

            значення,  яке  на  1  більше,  ніж  максимальне  серед  поточних
            значень  елементів  масиву  turn.  Потім  CS[i]  очікує,  поки
            значення  turn[i]  не  стане  найменшим  серед  ненульових
            елементів  масиву  turn.  Виходячи  з  критичної  секції,  процес

            CS[i] присвоює turn[i] значення 0.
                  У  лістингу  12  показаний  крупномодульний  варіант

            алгоритму  поліклініки,  у  якому  дотримано  зазначені  умови.
            Перша  неподільна  дія  забезпечує  унікальність  всіх  ненульових
            значень  елементів  масиву  turn.  Оператор  for  гарантує,  що
            інваріант має значення «істина», коли процес P[i] виконує свою

            критичну  секцію.  Даний  алгоритм  задовольняє  умові  взаємного
            виключення,  оскільки  одночасно  не  можуть  бути  істинними

            умови turn[i] != 0 для всіх i. Ненульові значення елементів
            масиву  turn  унікальні  і,  як  і  передбачалося,  кожен  процес
            зрештою  виходить  із  своєї  критичної  секції,  тому  взаємні
            блокування  відсутні.  Відсутні  також  зайві  затримки  процесів,

            оскільки відразу після виходу процесу CS[i] з критичної секції
            turn[i] отримує значення 0. Значення елементів масиву turn в

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


                  Лістинг 12 – Алгоритм поліклініки (крупномодульне рішення)

                  int turn[1: n] = ([n] 0);
                  process CS[i = 1 to n] {
                    while (true) {
                      <turn[i] = max(turn[1: n])+1;>
                      for [j = 1 to n st j!= i]
                        < await (turn[j] == 0 or turn[i] <turn[j]);>
                      критична секція;
                      turn[i] = 0;
                      некритична секція;

                                                        94
   90   91   92   93   94   95   96   97   98   99   100