Более сложной является ситуация, когда основной цикл приложения #8217 встроен в другую библиотеку или фреймворк. Такое приложение, как правило, после выполнения всех необходимых настроек передает управление некоторой форме функции run()
, от которой управление не возвращается до отключения приложения.
Программа Boost.Asio может называться io_service::run()
.
В общем, трюк заключается в том, чтобы организовать передачу управления на this_fiber::yield()
часто. Для этой цели можно использовать таймер Asio . Вы можете инстанцировать таймер, организуя вызов функции обработчика, когда таймер истекает. Функция обработчика может вызвать yield()
, затем сбросить таймер и организовать его повторное пробуждение при следующем истечении срока действия.
Поскольку в этом мысленном эксперименте мы всегда передаем управление диспетчеру волокон через yield()
, вызывающее волокно никогда не блокируется. Поэтому всегда есть хотя бы одно готовое волокно. Поэтому менеджер волокон никогда не вызывает алгоритм::suspend_until()
.
Использование io_service::post()
вместо установки таймера для некоторого ненулевого интервала было бы недружественным к другим потокам. Когда все ввод/вывод откладывается и все волокна блокируются, io_service и менеджер волокон просто вращают процессор, передавая управление друг другу. Использование таймера позволяет настроить отзывчивость этой нити относительно других.