Вызов pthread cond сигнала без блокировки мьютекса



Я где-то читал, что нужно запереть мьютекс перед вызовом pthread_cond_signal и разблокировать mutext после вызова его:




процедура pthread_cond_signal() является
используется для сигнала (или пробуждения) другого
нить, которая ждет на
переменная условия. Так и должно быть
вызывается после блокировки мьютекса и должен
разблокировать мьютекс для того, чтобы
pthread_cond_wait() обычной
полный.




мой вопрос: не это нормально, чтобы позвонить pthread_cond_signal или pthread_cond_broadcast методы без блокировки мьютекса?

660   3  

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

    Ничего не найдено.