Page 92 - 4868
P. 92

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

               очікує  на  подію,  виконуючи  операцію  P  для  відповідного  семафора,  і
               повідомляє про подію, виконуючи операцію V. Отримане рішення показано в
               лістингу 1.18.

                     Змінні empty та full в лістингу 1.18 є двійковими семафорами. Разом
               вони  утворюють  так  званий  спільний  двійковий  семафор,  оскільки  в  будь-
               який момент часу тільки один з них може мати значення 1. Термін «спільний
               двійковий  семафор»  зумовлений  тим,  що  змінні  empty  та  full  можуть
               розглядатися  як  єдиний  двійковий  семафор,  розділений  на  дві  частини.  У
               загальному випадку спільний двійковий семафор може бути утворений будь-
               яким числом двійкових семафорів.
                     Роль спільних двійкових семафорів особливо важлива під час реалізації
               взаємного  виключення.  Припустимо,  що  один  з  двійкових  семафорів
               ініціалізований  значенням  1  (відповідно,  інші  мають  значення  0).
               Припустимо,  що  в  процесах,  які  використовують  семафори,  кожна
               виконувана  гілка  починається  операцією  P  для  одного  із  семафорів  і
               закінчується  операцією  V  для  будь-якого  іншого  семафора.  Тоді  всі
               оператори  між  P  і  найближчою  операцією  V  виконуються  із  взаємним
               винятком,  тобто  якщо  процес  знаходиться  між  операціями  P  та  V,  то  всі
               семафори  рівні  0,  і,  отже,  жоден  процес  не  зможе  завершити  операцію  P,
               поки перший процес не виконає операцію V.

                     Лістинг  1.18  –  Виробники  та  споживачі,  що  використовують  спільні
               двійкові семафори

                     typeT buf; /* буфер типу T */
                     sem empty = 1, full = 0;
                     process Producer[і = 1 to M] {
                       while (true) {
                         ...
                         /* створити дані та помістити їх в буфер */
                         P(empty);
                         buf = data;
                         V(full);
                       }
                     }
                     process Consumer[j = 1 to N] {
                       while (true) {
                         /* отримати результат та обробити його */
                         P(full);
                         result = buf;
                         V(empty);
                       }
                     }

                     Рішення  задачі  про  виробників  і  споживачів  подане  в  лістингу  1.18
               ілюструє  застосування  спільних  двійкових  семафорів.  Кожен  процес-
               виробник  Producer  по  черзі  виконує  операції  P(empty)  та  V(full),  а
   87   88   89   90   91   92   93   94   95   96   97