Page 94 - 4868
P. 94

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

               споживач»),  то  виконання  операцій  deposit  та  fetch  має  чергуватися.  За
               наявності декількох буферів операцію deposit можна виконати, якщо існує

               порожня  клітинка,  a  fetch  –  якщо  збережено  хоча  б  одне  повідомлення.
               Фактично,  якщо  існує  порожня  клітинка  і  збережене  повідомлення,  то
               операції  deposit  та  fetch  можуть  виконуватися  одночасно,  оскільки
               звернення відбуваються до різних комірок масиву і вони не впливають одне
               на  одного.  Проте  вимоги  щодо  синхронізації  для  одноелементного  і
               кільцевого буфера однакові. Зокрема, використання операцій P та V є таким
               же  самим.  Єдина  відмінність  полягає  в  тому,  що  семафор  empty
               ініціалізується  значенням  n,  а  не  1,  оскільки  в  початковому  стані  існує  n
               порожніх комірок. Рішення даної задачі показано в лістингу 1.19.

                     Лістинг 1.19 – Реалізація кільцевого буфера з використанням семафорів
                     typeT buf[n]; /* буфер типу Т */
                     int front = 0, rear = 0;
                     sem empty = n, full = 0; /* N-2 <= empty + full <= n */
                     process Producer {
                       while (true) {
                         ...
                         створити повідомлення data;
                         /* помістити data в буфер */
                         P(empty);
                         buf[rear] = data;
                         rear = (rear+1) % n;
                         V(full);
                       }
                     }
                     process Consumer {
                       while (true) {
                         /* витягти та видалити повідомлення result */
                         P(full);
                         result = buf[front];
                         front = (front+1) % n;
                         V(empty);
                         ...
                       }
                     }

                     У  лістингу  1.19  семафори  грають  роль  лічильників  ресурсів.  Кожен
               враховує  кількість  елементів  ресурсу.  Змінна  empty  –  кількість  порожніх
               комірок  буфера,  a  full  –  заповнених.  Коли  жоден  процес  не  виконує
               операції  deposit  або  fetch,  сума  значень  обох  семафорів  дорівнює
               загальному  числу  комірок  n.  Виконуючі  облік  ресурсів  семафори
               використовуються у випадках, коли процеси конкурують за доступ до таких
               багатоелементних ресурсів, як комірки буфера або блоки пам’яті.
                     У  програмі  з  лістингу  1.19  передбачається,  що  існує  тільки  один
   89   90   91   92   93   94   95   96   97   98   99