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, що призводить до завершення головного потоку, проте інші
               потоки  продовжують  своє  виконання.  Кожен  потік  обчислює  суму  всіх
   122   123   124   125   126   127   128   129   130   131   132