Как стать автором
Обновить

Комментарии 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, которое было рассчитано на основе приоритетов таймеров в куче.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории