Якщо ви не зафіксуєте мьютекс у кодовій стежці, що змінює стан і сигнали, ви можете втратити активацію. Розглянемо цю пару процесів:
Процес A:
pthread_mutex_lock(&mutex);
while (condition == FALSE)
pthread_cond_wait(&cond, &mutex);
pthread_mutex_unlock(&mutex);
Процес B (неправильний):
condition = TRUE;
pthread_cond_signal(&cond);
Потім розгляньте це можливе чергування інструкцій, де condition
починається як FALSE
:
Process A Process B
pthread_mutex_lock(&mutex);
while (condition == FALSE)
condition = TRUE;
pthread_cond_signal(&cond);
pthread_cond_wait(&cond, &mutex);
Зараз condition
це TRUE
, але процес А застряг, чекаючи на змінну умови - він пропустив сигнал пробудження. Якщо ми змінимо процес B, щоб заблокувати мьютекс:
Процес B (правильний):
pthread_mutex_lock(&mutex);
condition = TRUE;
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
... тоді вищезазначене не може відбутися; пробудження ніколи не буде пропущено.
(Зверніть увагу, що ви можете насправді переміщати pthread_cond_signal()
себе після pthread_mutex_unlock()
, але це може призвести до менш оптимального планування потоків, і ви обов'язково заблокували мьютекс вже в цьому шляху коду через зміну самої умови).
pthread_signal_cond()
може бути переміщений після розблокування мьютексу, хоча, мабуть, краще не робити. Можливо, правильніше сказати, що в той момент, коли ви телефонуєтеpthread_signal_cond()
, вам вже потрібно було заблокувати мьютекс, щоб змінити саму умову.