Page 154 - 6571
P. 154

17.2 Керування потоками через семафори



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

                  них змінних.
                        Заголовочний файл semaphore.h включає в себе визначення
                  і  прототипи  операцій  для  семафорів.  Дескриптори  семафорів

                  визначені  як  глобальні  по  відношенню  до  потоків,  які  їх
                  використовують, наприклад:

                        sem_t mutex;

                        Дескриптор потоку ініціюється викликом функції sem_init.
                  Наприклад,  наступний  виклик  функції  sem_init  присвоює
                  семафору mutex значення 1:

                        sem_init(&mutex, SHARED, 1);

                        Якщо параметр SHARED не дорівнює нулю, то семафор може

                  бути  розподілений  між  декількома  процесами,  інакше  семафор
                  може використовувати тільки потоки одного процесу. Еквівалент

                  операції  P  в  бібліотеці  Pthreads  представлений  функцією
                  sem_wait,  а  операція  V  –  функцією  sem_post.  Отже,  один  із
                  способів захисту критичної секції за допомогою семафорів може
                  мати наступний вигляд.

                        sem_wait(&mutex); /* P(mutex) */
                          критична секція;
                        sem_post(&mutex); /* V(mutex) */

                        Крім того, в бібліотеці Pthreads визначені функції для умов-

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

                  «виробник-споживач»  з  використанням  бібліотеки  Pthreads.
                  Функції  Producer  та  Consumer  виконуються  як  незалежні
                  потоки.  Вони  розділяють  доступ  до  буферу  data.  Функція

                  Producer  поміщає  в  буфер  послідовність  цілих  чисел  від  1  до
                  значення numIters, а функція Consumer витягує і сумує їх. Для
                  забезпечення  спільного  доступу  до  буфера  для  процесу-




                                                             153
   149   150   151   152   153   154   155   156   157   158   159