Page 77 - 4868
P. 77

75                                                               Ошибка! Стиль не определен.


                     11.3. Алгоритм поліклініки
                     Алгоритм  квитка  можна  безпосередньо  реалізувати  на  машинах,  що
               мають  підтримку  операції  типу  «витягти  і  скласти».  Якщо  така  інструкція
               недоступна, то можна виконати моделювання її алгоритму роботи. Але для
               цього потрібен ще один протокол критичної секції, і рішення не обов’язково
               буде  мати  властивість  справедливості.  Представлений  тут  алгоритм
               поліклініки,  подібний  алгоритму  квитка.  Він  забезпечує  справедливість
               планування  і  не  вимагає  спеціальних  машинних  інструкцій.  Проте,  він
               складніший для практичної реалізації, ніж алгоритм квитка.
                     Згідно алгоритму квитка кожен відвідувач отримує унікальний номер  і
               очікує, поки значення змінної next не стане рівним цьому номеру. Алгоритм
               поліклініки  використовує  трохи  інший  підхід.  Заходячи  в  поліклініку,
               відвідувач дивиться на всіх інших і вибирає номер, який більший усіх інших
               вибраних номерів. Усі відвідувачі повинні чекати, поки не назвуть їх номер.
               Як і в алгоритмі квитка, наступним обслуговується відвідувач з найменшим
               номером.  Відмінність  полягає  в  тому,  що  для  визначення  черговості
               обслуговування  відвідувачі  звіряються  один  з  одним,  а  не  із  загальним
               лічильником.
                     Як  і  в  алгоритмі  квитка,  нехай  turn[1: n]  –  масив  цілих  чисел  з
               початковими  значеннями  0.  Щоб  увійти  в  критичну  секцію,  процес  CS[i]
               спочатку  присвоює  змінній  turn[i]  значення,  яке  на  1  більше,  ніж
               максимальне серед поточних значень елементів масиву  turn.  Потім CS[i]

               очікує,  поки  значення  turn[i]  не  стане  найменшим  серед  ненульових
               елементів  масиву  turn.  Виходячи  з  критичної  секції,  процес  CS[i]
               присвоює turn[i] значення 0.
                     У  лістингу  1.12  показаний  крупномодульний  варіант  алгоритму
               поліклініки,  у  якому  дотриманозазначені  умови.  Перша  неподільна  дія
               забезпечує  унікальність  всіх  ненульових  значень  елементів  масиву  turn.
               Оператор  for  гарантує,  що  інваріант  має  значення  «істина»,  коли  процес
               P[i]  виконує  свою  критичну  секцію.  Даний  алгоритм  задовольняє  умові
               взаємного виключення, оскільки одночасно не можуть бути істинними умови
               turn[i] != 0  для  всіх  i.  Ненульові  значення  елементів  масиву  turn
               унікальні  і,  як  і  передбачалося,  кожен  процес  зрештою  виходить  із  своєї
               критичної  секції,  тому  взаємні  блокування  відсутні.  Відсутні  також  зайві
               затримки процесів, оскільки відразу після виходу процесу CS[i] з критичної
               секції  turn[i]  отримує  значення  0.  Значення  елементів  масиву  turn  в
               алгоритмі  поліклініки  можуть  бути  як  завгодно  великі,  але  значення
               елементів масиву turn продовжують зростати, тільки у випадку, якщо є хоча
               б один процес, який намагається увійти в критичну секцію, однак на практиці
               це малоймовірно.
                     Алгоритм  поліклініки  в  лістингу  1.11  не  можливо  безпосередньо

               реалізувати на сучасних машинах. Щоб присвоїти змінній turn[i] значення,
               необхідно  знайти  максимальне  з  n  значень,  а  оператор  await  двічі
               звертається  до  спільної  змінної  turn[j].  Дані  операції  можна  було  б
   72   73   74   75   76   77   78   79   80   81   82