Page 51 - 6571
P. 51

Тепер ці два процеси працюють з різними рядками, записа-
            ними в змінні line1 і line2. Отже, процеси можуть виконувати-
            ся  паралельно.  Але  чи  правильна  ця  програма?  Звісно,  що  ні,
            оскільки перший процес весь час виконує пошук в line1, тоді як

            другий постійно виконує запис в line2.
                  Рішення даної проблеми є відносно простим: поміняємо ролі

            рядків даних в кінці кожного циклу, щоб перший процес завжди
            перевіряв останній зчитаний з файлу рядок, а другий процес зав-
            жди виконував запис в іншу змінну.

                  string line1, line2;
                  прочитати рядок вводу з stdin в line1;
                  while (!EOF) {
                    co
                      // шукати pattern в line1;
                         if (pattern є в line1) вивести line1;
                      // прочитати наступний рядок вводу в line2;
                    oc;
                    line1 = line2;
                  }

                  Наприкінці кожного циклу і після завершення кожного про-

            цесу вміст line2 копіюється в line1. Процеси всередині опера-
            тора co тепер незалежні, але їхні дії пов’язані через останній опе-

            ратор циклу, який копіює line2 в line1.
                  Паралельна  програма,  наведена  вище,  вірна,  але  абсолютно
            неефективна. По-перше, в останньому рядку циклу вміст змінної
            line2 копіюється в змінну line1. Така послідовна дія відсутня в

            першій програмі, і в загальному випадку вона вимагає копіюван-
            ня великої кількості символів, що призводить до накладних часо-
            вих затрат процесора. По-друге, в тілі циклу міститься оператор

            co,  а це означає, що  при кожному повторенні циклу while бу-
            дуть створюватися, виконуватися і знищуватися по два процеси.
            Копіювання  можна  зробити  набагато  ефективнішим,  використа-

            вши для цього масив з двома рядками. Індекси в кожному з про-
            цесів повинні вказувати на різні рядки масиву, а останній рядок
            визначається  шляхом  простого  обміну  значень  індексів  між  со-

            бою. Однак і в цьому випадку створювати процеси досить накла-
            дно, оскільки створення і знищення процесу займає набагато бі-
            льше часу, ніж виклик процедури або виконання лінійної ділянки
            коду.

                                                        50
   46   47   48   49   50   51   52   53   54   55   56