Page 127 - 4868
P. 127
125 Ошибка! Стиль не определен.
/* створити робочі потоки і вийти з головного потоку */
for (i = 0; i < numWorkers; i++)
pthread_create(&workerid[i], &attr, Worker, (void*) i);
pthread_exit(NULL);
}
/* кожен робочий потік підсумовує значення одного рядка */
/* після бар’єру потік worker(0) виводить загальну суму */
void* Worker(void* arg) {
int myid = (int) arg;
int total, i, j, first, last;
/* визначити перший та останній рядок */
first = myid * stripSize;
last = first + stripSize-1;
/* просумувати значення в рядку */
total = 0;
for (i = first; i <= last; i++)
for (j = 0; j < size; j++)
total += matrix[i][j];
sums[myid] = total;
Barrier();
if (myid == 0) {
/* процес з індексом 0 обчислює загальну суму */
total = 0;
for (i = 0; i < numWorkers; i++)
total += sums[i];
printf("Сума дорівнює %d\n", total);
}
}
Цілочисельні змінні та функція Barrier на початку лістингу2.2
реалізують повторно використовуваний бар’єр-лічильник. Вони не включені
в оголошення монітора, але ведуть себе так, ніби знаходяться в моніторі. Тіло
функції Barrier починається блокуванням м’ютекса і закінчується його
звільненням. Усередині функції процеси, які першими підійдуть до бар’єра,
очікують встановлення відповідного значення змінній go, після чого
скидають блокування монітора. Робочий процес, що підійшов до бар’єра
останнім, заново ініціалізує (обнуляє) змінну numArrived і запускає інші
робочі процеси за допомогою відповідного примітиву оповіщення. Робочі
процеси виконуються по одному, при цьому утримуючи м’ютекс. Кожен з
них після свого завершення знімає блокування з м’ютекса і виконує вихід з
функції Barrier.
У функції main виконується ініціалізація спільних змінних і
створюються відповідні потоки. Останній аргумент функції
pthread_create використовується для передачі потоку унікального
ідентифікатора. Функція main закінчує своє виконання викликом функції
pthread_exit, що призводить до завершення головного потоку, проте інші
потоки продовжують своє виконання. Кожен потік обчислює суму всіх