Как я могу использовать std::condition_variable
, чтобы разбудить нить и грациозно выйти из нее, пока она спит?Или есть ли другие способы достижения того же самого без техники condition_variable
?
Нет, не в стандартном C ++, а в C ++ 17 (конечно, есть нестандартные, специфичные для платформы способычтобы сделать это, и, вероятно, какой-то семафор будет добавлен в C ++ 2a).
Кроме того, я вижу, что мне нужно использовать std::mutex
в сочетании с std::condition_variable
?Это действительно необходимо?
Да.
Разве невозможно достичь цели, добавляя логику std::condition_variable
только в необходимые места в фрагменте кода здесь?
Нет.Для начала вы не можете ждать на condition_variable
без блокировки мьютекса (и передачи объекта блокировки в функцию ожидания), поэтому вам все равно нужно иметь мьютекс.Так как в любом случае вам нужно иметь мьютекс, требовать, чтобы и официант, и уведомитель использовали этот мьютекс, не такая уж большая проблема.
Переменные условия подвержены "ложным пробуждениям", что означает, что они могут перестать ждатьбез причины.Чтобы определить, проснулся ли он, потому что он был уведомлен или пробужден, вам нужна некоторая переменная состояния, которая устанавливается уведомляющим потоком и читается ожидающим потоком.Поскольку эта переменная совместно используется несколькими потоками, к ней необходимо безопасно обращаться, что обеспечивает мьютекс.
Даже если вы используете атомарную переменную для переменной общего доступа, вам все равно обычно требуется мьютекс, чтобы избежать пропущенных уведомлений.
Все это более подробно объясняется в https://github.com/isocpp/CppCoreGuidelines/issues/554