Вызов pthread cond сигнала без блокировки мьютекса
Я где-то читал, что нужно запереть мьютекс перед вызовом pthread_cond_signal и разблокировать mutext после вызова его:
процедура pthread_cond_signal() является
используется для сигнала (или пробуждения) другого
нить, которая ждет на
переменная условия. Так и должно быть
вызывается после блокировки мьютекса и должен
разблокировать мьютекс для того, чтобы
pthread_cond_wait() обычной
полный.
мой вопрос: не это нормально, чтобы позвонить pthread_cond_signal или pthread_cond_broadcast методы без блокировки мьютекса?
3 ответов:
если вы не заблокируете мьютекс в кодовом пути, который изменяет условие и сигналы, вы можете потерять пробуждения. Рассмотрим эту пару процессов:
Процесс 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);The
conditionтеперьTRUE, но процесс a застрял в ожидании переменная состояния-она пропустила сигнал пробуждения. Если мы изменим процесс B, чтобы заблокировать мьютекс:процесс B (правильный):
pthread_mutex_lock(&mutex); condition = TRUE; pthread_cond_signal(&cond); pthread_mutex_unlock(&mutex);...тогда вышесказанное не может произойти; пробуждение никогда не будет пропущено.
(обратите внимание, что вы можете на самом деле переместить после
pthread_mutex_unlock(), но это может привести к менее оптимальному планированию потоков, и вы обязательно заблокировали мьютекс уже в этом пути кода из-за изменения само условие).
согласно этому руководству :
The
pthread_cond_broadcast()илиpthread_cond_signal()функции может быть вызван потоком независимо от того, является ли он в настоящее время владельцем мьютекса что темы с призывамиpthread_cond_wait()илиpthread_cond_timedwait()есть связанный с переменной условия во время их ожидания; однако, если предсказуемое поведение планирования требуется, то что мьютекс должен быть заблокирован вызовом потокаpthread_cond_broadcast()илиpthread_cond_signal().смысл предсказуемое поведение планирование заявление пояснил Дэйв Butenhof (автор Программирование с потоками POSIX) на комп.программирование.темы и доступно здесь.
caf, в вашем примере кода, процесс B изменяет
conditionбез блокировки мьютекса в первую очередь. Если процесс B просто заблокировал мьютекс во время этой модификации, а затем все еще разблокировал мьютекс перед вызовомpthread_cond_signal, не было бы никаких проблем --- я не ошибся?я интуитивно верю, что caf позиция правильно: вызов
pthread_cond_signalбез владения блокировкой мьютекса это плохая идея. Но КАФ пример на самом деле не является доказательством в поддержку эта позиция; это просто свидетельство в поддержку гораздо более слабой (практически самоочевидной) позиции, что это плохая идея изменить общее состояние, защищенное мьютексом, если вы не заблокировали этот мьютекс в первую очередь.может ли кто-нибудь предоставить пример кода, в котором вызов
pthread_cond_signalзатемpthread_mutex_unlockдает правильное поведение, но вызовpthread_mutex_unlockследовал поpthread_cond_signalприводит к неправильному поведению?
Comments