40 / 29 / 11
Регистрация: 21.06.2019
Сообщений: 201
|
||||||
1 | ||||||
Как устроен condition_variable::wait?14.12.2020, 17:15. Показов 4357. Ответов 5
Всем привет, изучаю c_v стандартной библиотеки и возник вопрос что происходит когда condition_variable::wait захватывает поток и он не соответствует условию в предикате? Мне казалось что там вечный цикл который и проверяет этот предикат (собственно по нему он и будит поток). Однако такой код не выводит "sleep" более 1 раза для уснувшего потока, вопрос: почему так? Что там происходит если не постоянная проверка предиката в цикле?
0
|
14.12.2020, 17:15 | |
Ответы с готовыми решениями:
5
Condition_variable - как заставить работать все пробужденные потоки Как устроен std::string Как устроен любой API? Как устроен вектор (STL) ? |
6579 / 4564 / 1843
Регистрация: 07.05.2019
Сообщений: 13,726
|
||||||
14.12.2020, 17:26 | 2 | |||||
condition_variable::wait ждёт, пока другой поток не вызовет condition_variable::notify_all/notify_one
Добавлено через 1 минуту
При вызове cv.wait(lk) поток усыпляется
1
|
1538 / 458 / 101
Регистрация: 17.05.2015
Сообщений: 1,426
|
|
14.12.2020, 17:30 | 3 |
Нет там никаких циклов.
Когда поток спит - он полностью заморожен. Он не расходует ресурсы машины. Не грузит процессор. Его память может быть отдана другим процессам. Поток будет спать до тех пор, пока его не разбудит ОС. Система будет поток по особому системному событию. Так же, в случае с condition_variable могут быть ложные срабатывания. В этом случае поток "ничайно" просыпается раньше времени. Затем запускается предикат, и если он возвращает: "ложная тревога!", тогда поток спит дальше.
1
|
40 / 29 / 11
Регистрация: 21.06.2019
Сообщений: 201
|
||||||
14.12.2020, 17:42 [ТС] | 4 | |||||
oleg-m1973, вопрос был не про это, а про то, что происходит внутри wait, как он проверяет условия предиката?
https://en.cppreference.com/w/... iable/wait - 2 перегрузка. Я зашел внутрь файла condition_variable и там написано это:
eva2326, хорошо, я подозревал что wait внутри cv::wait - это уже системный вызов. Если так оно и есть - тогда это логично, спасибо за ответ! Получается notify_one тоже взывает к ОС? Следовательно вызывать его довольно дорого? :\
1
|
6579 / 4564 / 1843
Регистрация: 07.05.2019
Сообщений: 13,726
|
|
14.12.2020, 17:50 | 5 |
Я тебе вроде это и показал
Добавлено через 4 минуты Кстати, можно было никуда не заходить, а просто посмотреть описание https://en.cppreference.com/w/... iable/wait
0
|
Вездепух
11696 / 6375 / 1724
Регистрация: 18.10.2014
Сообщений: 16,078
|
|
14.12.2020, 19:35 | 6 |
Сообщение было отмечено HamsterGamer как решение
Решение
Это какое-то самопротиворечащее утверждение. Если поток спит, то кто же тогда выполняет этот "вечный цикл"? Если поток не спит, то о каком "будит" может идти речь?
Никакого "вечного цикла" (то есть постоянно активного цикла) там нет. Поток полноценно спит, то есть система прекращает его выполнение полностью, то тех пор пока какой-то другой поток не "дернет" этот condition variable. Однако не стоит забывать про возможность spurious wakeup: поток может вдруг ни с того ни с сего проснуться без причины (то есть даже если никто не дергал эту condition variable), проверить предикат и снова лечь спать. То есть (теперь уже поправляя самого себя) цикл-то там, конечно, нужен, именно для того, чтобы в какой-то момент проснуться, проверить предикат и, возможно, снова лечь спать. Но каждая итерация этого цикла полноценно укладывается спать. В идеальном случае такой цикл все время спит, просыпается только один раз и в итоге делает ровно одну итерацию, что вы и наблюдаете в своих экспериментах. Так и должно быть. Пока поток "спит" предикат никто не проверяет. Когда поток просыпается, он один раз проверяет предикат, чтобы убедиться, что "пора просыпаться" и просыпается. Но еще раз, из-за spurious wakeup, если оно вдруг произойдет, теоретически поток может вывести "sleep" более 1 раза. То есть теоретически поток может спать "неспокойным сном": периодически неожиданно просыпаться без причины, проверять предикат, понимать, что это случайное ненужное пробуждение, и снова укладываться спать. Читаем литературу на тему того, как устроен системный планировщик задач (task scheduler) и что такое состояние "sleep" для потока.
1
|
14.12.2020, 19:35 | |
14.12.2020, 19:35 | |
Помогаю со студенческими работами здесь
6
C++11, потоки, std::condition_variable Как устроен const std::vector Не понятно как работает пример std::condition_variable::wait Как устроен QtCreator Как устроен таймер? Как устроен криптор? Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |