Как будет вести себя цикл while, включающий pthread_cond_wait? - PullRequest
0 голосов
/ 12 мая 2019

Я хотел бы знать, что происходит с while после пробуждения ожидающей нити.

Чтобы избежать «ложных пробуждений», в документации pthreads указано, что вам нужно использовать pthread_cond_wait внутри оператора while.

Итак, когда вызывается pthread_cond_wait, вызывающий поток блокируется. И после того, как дал сигнал, поток возобновить внутри while.

В моем коде я обрабатываю pthread_cond_wait() следующим образом:

pthread_mutex_lock(&waiting_call_lock);
while(1) {
    pthread_cond_wait(&queue_cond[thread_ctx], &waiting_call_lock);
    break;
}
pthread_mutex_unlock(&waiting_call_lock);

Вопрос в том, будет ли он пытаться ввести время снова или как-то это break время и продолжить? Или, в этом случае, break после pthread_cond_wait() необходимо?

1 Ответ

2 голосов
/ 12 мая 2019

Чтобы понять это правильно, я думаю, что лучше всего начать с вопроса: «чего ждет поток?»

Ответ не должен быть «он должен ждать, пока другой поток не сообщит об этом», потому что способ, которым работают переменные условия, предполагает, что у вас есть что-то еще, какая-то информация, защищенная от мьютекса, которую поток должен ждать.

Чтобы проиллюстрировать это, я приведу здесь пример, где поток должен ждать, пока переменная с именем counter не станет больше 7. Переменная counter доступна нескольким потокам и защищена мьютексом, который я буду использовать. Звоните theMutex. Тогда код, включающий вызов pthread_cond_wait, может выглядеть так:

pthread_mutex_lock(&theMutex);
while(counter <= 7) {
    pthread_cond_wait(&cond, &theMutex);
}
pthread_mutex_unlock(&theMutex);

Теперь, если произойдет «ложное пробуждение», программа снова проверит условие (counter <= 7) и обнаружит, что оно все еще не выполнено, поэтому будет оставаться в цикле и снова вызовет pthread_cond_wait. Таким образом, это гарантирует, что поток не будет проходить после цикла while, пока не будет выполнено условие.

Поскольку ложные пробуждения на практике случаются редко, может быть интересным инициировать их, чтобы убедиться, что ваша реализация работает должным образом; Вот обсуждение этого вопроса: Как вызвать ложное пробуждение в приложении Linux?

...