Page 125 - 4868
P. 125
123 Ошибка! Стиль не определен.
pthread_mutex_lock(&mutex);
критична секція;
pthread_mutex_unlock(&mutex);
Розблокувати м’ютекс можна тільки з потоку, що утримує блокування.
Існує також і неблокуюча версія оператора lock.
Умовні змінні бібліотеки Pthreads, як і м’ютекси, характеризуються
дескрипторами і атрибутами. Умовна змінна оголошується та ініціалізується
атрибутами по замовчуванню як показано нижче.
pthread_cond_t cond;
...
pthread_cond_init(&cond, NULL);
Основні операції над умовними змінними (очікування (wait),
сигналізація (signal) і сповіщення (broadcast)), аналогічні оператору
signal_all. Вони виконуються під час блокування м’ютекса. Наприклад,
процедура монітора при використанні бібліотеки Pthreads імітується за
допомогою блокування м’ютекса на початку виклику процедури і зняття
блокування в кінці її иконання.
Параметрами процедури pthread_cond_wait виступає умовна змінна і
блокування м’ютекса. Потік, що переводиться в режим очікування, спочатку
повинен отримати блокування. Нехай, наприклад, потік уже виконав виклик
функції
pthread_mutex_lock(&mutex);
і після цього виконує виклик функції
pthread_cond_wait(&cond, &mutex);
У результаті таких дій потік звільняє mutex і очікує встановлення
відповідного значення для змінної cond. Коли процес поновляє своє
виконання після сигналізування або оповіщення, то потік знову отримує
контроль над м’ютексом і блокує його. Якщо код
pthread_cond_signal(&cond);
виконується в іншому потоці, то відбувається запуск одного із заблокованих
потоків, проте, при цьому сигнальний потік продовжує свою роботу і
утримує м’ютекс.
У лістингу 2.2 подано закінчену версію програми, в якій
використовуються блокування і умовні змінні. У програмі створюється
numWorkers потоків для підсумовування елементів масиву matrix розміром
size. Хоча особливої практичної користі даний приклад не має, проте його
структура і компоненти є типовими для синхронних паралельних ітераційних
обчислень.
Лістинг 2.2 – Паралельне підсумовування елементів матриці
#include <pthread.h>