Комментарии 4
Спасибо за подробное исследование. Сам горю желанием реализовать однопоточную многозадачность на манер Nodejs в слабом восьмибитном применении и твою статью буду использовать как референс.
Здравствуйте! Спасибо за статью! Но лично меня все еще мучает вопрос, как обрабатывается такой случай:
1) мы поставили таймер на 1000 секунд например
2) запускаем цикл событий
3) он засыпает на 1000 секунд (был этот один единственный таймер ведь в куче)
4) вдруг по ходу приложения мы ставим таймер на 2 секунды
Вопрос: неужто этот таймер 2 секундный
а) будет ждать 1000 секунд, пока цикл не выйдет из еполла?
б) или там как-то динамически в еполл закинут его дескриптор и ждать не придется?
Спасибо
Здравствуйте! Остановимся подробнее на 4 пункте. Если мы смогли поставить еще один таймер на 2 секунды, это значит, что ожидание было прервано, и мы из него вышли (из epoll_wait) и запустили новый таймер в каком-то обработчике. Этот таймер будет добавлен в кучу. В каком месте этот таймер будет в куче зависит от итогового приоритета для этого таймера, который, как мы помним, рассчитывается как сумма времени цикла и таймаута. Затем уже на следующей итерации цикла событий мы опять входим в epoll_wait, в который передается заново рассчитанный таймаут на основе уже двух таймеров в куче.
Поэтому вариант а) не случится, потому что, раз мы смогли по ходу приложения поставить новый таймер, значит ожидание уже было прервано. По поводу варианта б) - у таймеров нет каких-то дескрипторов, которые были бы интересны для epoll, у них есть приоритет.
int epoll_wait(
int epfd,
struct epoll_event *events,
int maxevents,
int timeout
);
И для epoll_wait нужно только значение timeout, которое было рассчитано на основе приоритетов таймеров в куче.
Куча таймеров в node.js