Если вы не заблокируете мьютекс в пути кода, который изменяет условие и сигналы, вы можете потерять пробуждения. Рассмотрим эту пару процессов:
Процесс 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
, но процесс A застрял в ожидании переменной условия - он пропустил сигнал пробуждения. Если мы изменим Процесс B, чтобы заблокировать мьютекс:
Процесс B (правильный):
pthread_mutex_lock(&mutex);
condition = TRUE;
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
... тогда вышеупомянутое не может произойти; пробуждение никогда не будет пропущено.
(Обратите внимание, что вы можете фактически переместить pthread_cond_signal()
после pthread_mutex_unlock()
, но это может привести к менее оптимальному планированию потоков, и вы обязательно заблокировали мьютекс уже в этом коде путь из-за изменения самого условия).