Первый не в порядке:
pthread_cond_timedwait()
и
pthread_cond_wait()
функции должны
блок на условной переменной. Oни
должен вызываться с мьютексом, заблокированным
вызывающая нить или неопределенная
результаты поведения.
http://opengroup.org/onlinepubs/009695399/functions/pthread_cond_timedwait.html
Причина в том, что реализация может захотеть заблокировать мьютекс, чтобы безопасно добавить вас в список официантов. И он может захотеть освободить мьютекс без предварительной проверки его удержания.
Второй тревожит:
если прогнозируемое поведение планирования
требуется, то этот мьютекс заблокирован
вызывающая нить
pthread_cond_signal()
или
pthread_cond_broadcast()
.
http://www.opengroup.org/onlinepubs/007908775/xsh/pthread_cond_signal.html
Сверху головы, я не уверен, что это за конкретное состояние гонки, которое портит поведение планировщика, если вы сигнализируете без взятия блокировки. Так что я не знаю, насколько плохим может быть неопределенное поведение планировщика: например, возможно, с широковещательной передачей официанты просто не получают блокировку в приоритетном порядке (или, тем не менее, ваш конкретный планировщик обычно ведет себя). Или, может быть, официанты могут потеряться.
Как правило, однако, с помощью переменной условия вы хотите установить условие (по крайней мере, флаг) и сигнал, а не просто сигнал, и для этого вам нужно взять мьютекс. Причина в том, что в противном случае, если вы работаете одновременно с другим потоком, вызывающим wait (), вы получаете совершенно другое поведение в зависимости от того, выиграют ли wait () или signal (): если в первый раз подойдет signal (), то вы дождитесь полного таймаута, даже если сигнал, который вас волнует, уже произошел. Это редко то, что хотят пользователи условных переменных, но может подойти вам. Возможно, именно это и подразумевают в документах «непредсказуемое поведение планировщика» - внезапно временной интервал становится критическим для поведения вашей программы.
Кстати, в Java для блокировки notify () или notifyAll () необходимо иметь блокировку:
Этот метод должен вызываться только
Нить, которая является владельцем этого
монитор объекта.
http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Object.html#notify()
Синхронизированное поведение Java {/} / wait / notifty / notifyAll аналогично pthread_mutex_lock / pthread_mutex_unlock / pthread_cond_wait / pthread_cond_signal / pthread_cond_broadcast, и не случайно.