Waker и паттерн пейджераОкей, Future вернула управление (сказала
Poll::Pending). Но как рантайм узнает, что данные по сети пришли и пора снова вызвать poll()? Если он будет постоянно опрашивать все Future в цикле (while loop), ваш CPU улетит в космос на 100% загрузке.Здесь на сцену выходят Executor, Reactor и Waker.
• Executor - это менеджер задач. Он берет Future и вызывает у нее
poll().• Reactor - это слушатель ОС (обертка над
epoll в Linux, kqueue в macOS или IOCP в Windows). Он ждет событий от сетевой карты или диска.• Waker - это тот самый пейджер, который выдают в бургерной.
Как это работает:
1. Future делает сетевой запрос и понимает, что данных еще нет.
2. Она регистрирует этот запрос в Reactor и отдает ему свой Waker (колбэк, в котором зашит ID этой Future).
3. Future возвращает
Pending. Executor забывает про неё и идет выполнять другие задачи.4. ...проходит время... Сетевая карта получает пакеты. ОС дергает
epoll.5. Reactor видит: "Ага, пришли данные для сокета X". Он берет Waker, привязанный к этому сокету, и вызывает
waker.wake().6. Waker сигнализирует Executor'у: "Задача #42 готова, помести её обратно в очередь на выполнение".
7. Executor снова вызывает
poll(), и стейт-машина делает следующий шаг.Никакого холостого хода CPU. Только чистая событийная архитектура.
#rust #async #waker #tokio #epoll
👉 @rust_lib