цикл условия pthread - PullRequest
       5

цикл условия pthread

2 голосов
/ 21 декабря 2010

Типичный шаблон, который я видел для использования pthread_cond_wait:

pthread_mutex_lock(&lock);
  while (!test)
    pthread_cond_wait(&condition, &lock);
pthread_mutex_unlock(&lock);

Почему нельзя использовать оператор if вместо цикла while.

pthread_mutex_lock(&lock);
  if (!test)
    pthread_cond_wait(&condition, &lock);
pthread_mutex_unlock(&lock);

Ответы [ 3 ]

9 голосов
/ 21 декабря 2010

http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_cond_timedwait.html

При использовании условных переменных всегда существует логический предикат, включающий общие переменные, связанные с каждым условным ожиданием, которое имеет значение true, если поток должен продолжаться.Могут возникнуть ложные пробуждения от функций pthread_cond_timedwait () или pthread_cond_wait ().Поскольку возврат из pthread_cond_timedwait () или pthread_cond_wait () ничего не подразумевает в значении этого предиката, предикат должен быть повторно оценен после такого возврата.

Цикл while оченьстандартный способ переоценки предиката, как того требует POSIX.

1 голос
/ 15 сентября 2011

Есть две причины.Один из них - ложные пробуждения, как уже упоминалось в других ответах.Другой - это настоящие пробуждения.Представьте себе:

У вас есть два потока, A и B, заблокированные в одной и той же условной переменной, которая защищает очередь, очередь пуста.Какой-то поток помещает задание в очередь, вызывая поток A. Другой поток помещает задание в очередь, вызывая поток B. Поток A запускается первым и выполняет первое задание.Он возвращается к if и видит, что условие все еще выполняется (поскольку есть вторая работа), поэтому он тоже выполняет эту работу.Теперь поток B получает процессор, возвращаясь из pthread_cond_wait, но предикат не ложный, поскольку очередь пуста.

Вы знаете, что предикат был истинным, когда какой-то другой поток просил вас разбудить,У вас нет возможности узнать, что это все равно будет правдой, когда вы наконец-то получите расписание и сможете повторно получить мьютекс.

1 голос
/ 21 декабря 2010

if возможно, но используется редко.Вам просто нужно быть уверенным, что состояние вашего приложения соответствует состоянию, когда вы выходите из wait.Обычно вам нужно убедиться, что вы используете pthread_cond_signal на другом конце (а не broadcast), например

...