Зачем вам нужен цикл while во время ожидания условной переменной - PullRequest
12 голосов
/ 14 октября 2011

Скажем, у вас есть этот код

pthread_mutex_lock(&cam->video_lock);
while(cam->status == WAIT_DISPLAY) // <-- Why is this a 'while' and not an 'if'?
    pthread_cond_wait(&cam->video_cond, &cam->video_lock);
pthread_mutex_unlock(&cam->video_lock);

Мой вопрос: зачем вам нужен цикл while здесь.Разве pthread_cond_wait просто не подождет, пока сигнальный поток не выдаст сигнал cam_video_cond ?Хорошо, я знаю, что у вас может быть случай, когда cam-> status не равен WAIT_DISPAY , когда вызывается pthread_cond_wait , но в этом случае вы можете просто проверитьэто через если условие вместо использования в то время как .

Я что-то здесь упускаю?Насколько я понимаю, pthread_cond_wait заключается в том, что он просто ждет бесконечности, если cam_video_cond не сигнализируется.Кроме того, он разблокирует мьютекс cam_video_lock при вызове, но когда сигнализируется условие, перед возвратом он блокирует cam_video_lock .Я прав?

Ответы [ 3 ]

19 голосов
/ 14 октября 2011

Рекомендуется, чтобы все потоки проверяли состояние после возврата от pthread_cond_wait , потому что есть несколько причин может не быть правдой. Одна из этих причин - ложное пробуждение; то есть, может проснуться нить, хотя ни одна нить не состояние. * * 1004

Источник: Ложное пробуждение

13 голосов
/ 27 октября 2011

Ложные пробуждения - это одна из причин, а законные, но посторонние пробуждения - другая.

Рассмотрим:

  1. Вы поставили работу в очередь.

  2. Вы сигнализируете переменную условия, пробуждая поток A.

  3. Вы ставите задание в очередь.

  4. Высигнализировать переменную условия, пробуждая поток B.

  5. Поток A назначается по расписанию, выполняет первую работу.

  6. Поток A находит очередь безпустой и выполняет второе задание.

  7. Поток B запланирован, будучи разбуженным, но находит очередь все еще пустой.

2 голосов
/ 14 октября 2011

По соображениям производительности API POSIX позволяет ОС пробуждать ваш поток, даже если условие не было выполнено (это называется ложным пробуждением ).

...