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