Page 158 - 6571
P. 158

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

                  використовуються  блокування  і  умовні  змінні.  У  програмі
                  створюється numWorkers потоків для підсумовування елементів

                  масиву  matrix  розміром  size.  Хоча  особливої  практичної
                  користі даний приклад не має, проте його структура і компоненти
                  є типовими для синхронних паралельних ітераційних обчислень.


                        Лістинг 32 – Паралельне підсумовування елементів матриці
                        #include <pthread.h>
                        #include <stdio.h>
                        #define SHARED 1

                        #define MAXSIZE 2000 /* максимальний розмір матриці */
                        #define MAXWORKERS 4 /* максимальне число робочих пото-
                  ків */

                        pthread_mutex_t barrier;   /* блокування для бар’єру */
                        pthread_cond_t go;                     /* умовна змінна */
                        int numWorkers;                        /* число робочих потоків */
                        int numArrived = 0;        /* кількість потоків, */
                                                               /*що підійшли до бар’єру */
                        /* повторно використовуваний бар’єр-лічильник */
                        void Barrier() {
                          pthread_mutex_lock(&barrier);
                          numArrived++;
                          if (numArrived < numWorkers)
                            pthread_cond_wait(&go, &barrier);
                          else {
                            numArrived = 0;               /* останній робочий потік */
                                            /*запускає інші потоки*/
                            pthread_cond_broadcast(&go);
                          }
                          pthread_mutex_unlock(&barrier);
                        }

                        void* Worker (void*);
                        int size, stripSize;  /* size == stripSize * numWorkers
                  */
                        int sums[MAXWORKERS]; /* cуми, обчислені кожним потоком
                  */


                                                             157
   153   154   155   156   157   158   159   160   161   162   163