Поток изредка зависает на ожидании condition_variable
Рабочий поток забирает задания из очереди:
std::unique_lock<std::mutex> lk(m);
cv.wait(lk);
Job job = queue.pop(); // очередь непустая — так предполагает код
Под нагрузкой поток изредка застревает в ожидании навсегда, а иногда падает при извлечении из пустой очереди. Что не так с этим кодом?
- Вместо unique_lock здесь нужен lock_guard: он удерживает мьютекс всё время ожидания, поэтому уведомления не теряются и ложных пробуждений не бывает
- Уведомляющая сторона обязана вызывать notify под тем же мьютексом, иначе ожидающий поток не проснётся никогда
- Уведомление, посланное до входа в wait, теряется, а ложное пробуждение ведёт к чтению из пустой очереди: нужен предикат
- Очередь не объявлена volatile, поэтому ожидающий поток видит устаревшее значение её размера и лезет в пустую
