Page 118 - 6571
P. 118

жоден  процес  не  виконує  операції  deposit  або  fetch,  сума
                  значень  обох  семафорів  дорівнює  загальному  числу  комірок  n.
                  Виконуючі  облік  ресурсів  семафори  використовуються  у

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

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

                  одночасно.  Але  тоді  обидва  намагалися  б  помістити  свої
                  повідомлення в одну і ту ж комірку. Аналогічно, якщо є декілька

                  споживачів,  два  з  них  одночасно  можуть  виконати  fetch  і
                  отримати одне й те саме повідомлення. Таким чином, deposit та
                  fetch  перетворюються  на  критичні  секції.  Однакові  операції
                  повинні  виконуватися  із  взаємним  винятком,  але  різні  можуть

                  виконуватися одночасно, оскільки при роботі семафорів empty та
                  full  виробники  і  споживачі  звертаються  до  різних  комірок

                  буфера.  Необхідне  взаємне  виключення  можна  реалізувати,
                  використовуючи рішення для задачі критичної секції з окремими
                  семафорами  для  захисту  кожної  критичної  секції  (лістинг  16).
                  Закінчене рішення описаної задачі приведене в лістингу 20.

                        Лістинг 20 – Декілька виробників і споживачів, що викорис-
                  товують семафори

                        typeT buf[n]; /* масив типу Т */
                        int front = 0, rear = 0;
                        sem empty = n, full = 0; /* N-2 <= empty + full <= n */
                        sem mutexD = 1, mutexF = 1; /* взаємне виключення */
                        process Producer[i = 1 to M] {
                          while (true) {
                            ...
                            створити повідомлення data;
                            /* помістити data в буфер */
                            P(empty);
                            P(mutexD);
                            buf[rear] = data;
                            rear = (rear+1) % n;
                            V(mutexD);
                            V(full);
                          }

                                                             117
   113   114   115   116   117   118   119   120   121   122   123