Page 102 - 6571
P. 102

Але в такому випадку знову виникають конфлікти звернення
                  до  пам’яті,  причому  таке  рішення  є  досить  неефективним,
                  оскільки  суму  елементів  arrive[i]  тепер  постійно  обчислює
                  кожен очікуючий своєї черги процес Worker.

                        Обидві  проблеми  (конфлікти  звернення  до  пам’яті  і
                  обнулення  масиву)  можна  вирішити,  використавши  додатковий

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

                  «істина».  Нехай  continue[1: n]  –  додатковий  масив  цілих
                  чисел  з  нульовими  початковими  значеннями.  Після  того  як
                  процес  Worker[i]  присвоїть  значення  1  елементу  масиву

                  arrive[i], він переводиться в режим очікування до того часу,
                  доки значенням змінної continue[i] не стане 1.

                        arrive[i] = 1;
                        <await (continue[i] == 1);>

                        Процес  Coordinator  очікує,  поки  всі  елементи  масиву
                  arrive  не  стануть  рівні  1,  а  потім  присвоює  значення  1  всім

                  елементам масиву continue.

                        for [i = 1 to n] < await (arrive[i] == 1);>
                        for [i = 1 to n] continue[i] = 1;

                        Оператори await можна реалізувати у вигляді циклів while,
                  оскільки кожен із них посилається лише на одну спільну змінну.
                  У  процесі  Coordinator  для  очікування  процедури  присвоєння

                  значень  всім  елементам  arrive  можна  використати  оператор
                  for. Оскільки для продовження роботи процесів Worker повинні
                  бути встановлені значення для усіх елементів масиву arrive, то

                  процес Coordinator може перевіряти їх у довільному порядку.
                  Конфліктів звернення до пам’яті тепер не буде, оскільки процеси

                  очікують зміни різних змінних, кожна з яких може зберігатися у
                  своєму рядку кеш-пам’яті.
                        Змінні  arrive  та  continue  в  представлених  програмах  є
                  прикладами  так  званого  прапорця.  Його  встановлює  (піднімає)

                  один  процес,  щоб  повідомити  іншого  про  виконання  умови
                  синхронізації. Доповнимо програми кодом, який скидає прапорці
                  (присвоюючи  їм  значення  0)  для  підготовки  їх  до  наступної

                  ітерації.  При  цьому  використовуються  два  основних  правила

                                                             101
   97   98   99   100   101   102   103   104   105   106   107