Ответ 1
Почему требуется блокировка мьютекса перед вызовом pthread_cond_wait?
Потому что в противном случае существует неизбежное состояние гонки.
Мьютекс защищает разделяемое состояние. Переменная условия связана с некоторым предикатом ( "условие" ) в состоянии. Основная идея заключается в том, что вы хотите:
1) проверьте предикат
2), если предикат ложный, перейдите в режим сна, пока он не станет истинным.
В параллельной системе для некоторого потока всегда возможно сделать предикат true между (1) и (2). Чтобы избежать этой гонки, вы должны удерживать мьютекс до (1), и вы должны его атомизировать при выполнении (2).
Например, для очереди предикат может быть "очередь не пустая". Но между тем, как вы проверяете, не очередь ли очередь и время, когда вы идете спать, какой-то другой поток может добавить что-то в очередь.
Таким образом, вы должны держать мьютекс как при проверке предиката, так и при вызове pthread_cond_wait.
Кроме того, требуется ли сделать блокировку (в том же мьютексе) перед вызовом pthread_cond_signal?
Насколько мне известно, нет фундаментальной проблемы с этим; это просто вводит потенциальную неэффективность.
Здесь снова, любое разделяемое состояние, которое вы изменяете (и, таким образом, предикат true), должно быть защищено мьютезом. Поэтому в любое время, когда вы хотите сигнализировать о состоянии, вы все равно должны иметь мьютекс.
Если вы отпустите мьютекс перед сигналом условия, предикат может стать ложным между ними из-за действия какого-либо другого потока. Эта гонка не вызывает сбоев, потому что любой поток, ожидающий состояния, должен в любом случае дважды проверять предикат, прежде чем продолжить... Но почему это вызвало проблему?
Нижняя строка: просто следуйте инструкциям, и вам даже не нужно думать об этих вопросах.: -)