Привет, Дипал Джаясекара.
Спасибо, что ответили на мои вопросы в одном из ваших предыдущих сообщений в блоге. Ваш вклад был действительно полезен. Я очень ценю это!
У меня снова есть несколько вопросов. Было бы здорово, если бы вы помогли мне еще раз прояснить некоторые вещи.
- У меня вопрос по ручкам и запросам. Вы писали о них несколько раз в своем посте. Например:
uv__loop_alive
— Проверяет, есть ли какие-либо обработчики, на которые есть ссылки, которые нужно вызвать, или какие-либо активные ожидающие операции
Or:
Если нет активных дескрипторов или ожидающих активных операций, нет смысла ждать, поэтому тайм-аут равен
0
.
Они используются в некоторых функциях. В этом:
И этот:
Я не понимаю, что проверяют функции uv__has_active_handles
и uv__has_active_reqs
? Что такое ссылочные обработчики и активные запросы/операции (как я вижу, вы используете запросы и операцию взаимозаменяемо )?
Про дескрипторы и запросы я уже читал в документации Libuv, но до сих пор не могу понять. Трудно понять без реальных словесных примеров. Может быть, обработчик — это что-то вроде fs
, а запрос/операция — просто http
запрос? Обработчики вызываются в пуле потоков Libuv, а любые запросы/операции обрабатываются в AIO ядра (например, epoll
в Linux)?
Вот как я понимаю: функция uv__has_active_handles
проверяет, есть ли какие-то незавершенные задачи в пуле потоков Libuv (например, чтение содержимого файла с помощью fs
). Если есть незавершенные задачи, эта функция возвращает true
. Как только эти задачи будут завершены, соответствующие события будут запущены, а их обратные вызовы будут добавлены в файл pending_queue
. Та же логика с запросами/операциями (но uv__has_active_reqs
проверяет, нет ли недоделок на AIO ядра). Я не уверен, прав я или нет.
2. Вы написали:
Если
pending_queue
пусто, эта функция вернет0
. В противном случае будут выполнены все обратные вызовы вpending_queue
, и функция вернет1
.
К этой фразе вопросов нет. Прекрасно это понимаю. Вопрос в том, почему режим UV_RUN_ONCE
зависит от результата функции uv__run_pending
? Вы написали:
Если цикл событий выполняется на
UV_RUN_ONCE
и еслиuv_run_pending
возвращает0
(т. е.pending_queue
пусто),timeout
вычисляется с использованием методаuv_backend_timeout
.
Какая разница для цикла обработки событий, работающего в режиме UV_RUN_ONCE
, был ли был некоторый обратный вызов в режиме pending_queue
или нет? Если возвращается 0
, это означает, что обратных вызовов не было. Если возвращается 1
, это означает, что были какие-то обратные вызовы, но в любом случае — они были выполнены. Почему мы не можем дождаться опроса ввода-вывода, если раньше в pending_queue
были какие-то обратные вызовы. В любом случае, мы их выполнили, и pending_queue
будет пустым.
3. Вы написали:
Если есть ожидающие выполнения дескрипторы бездействия, ожидание ввода-вывода не должно выполняться.
Что это за холостые ручки? К сожалению, я не нашел никакой информации об этом этапе в ваших сообщениях. Насколько я понимаю, они выполняются в течение этой фазы uv__run_idle
. Не могли бы вы привести пример из мира Node.js? Обратные вызовы setImmediate
выполняются на этапе uv__run_check
… а какие обратные вызовы выполняются на этапе uv__run_idle
?
4. Также, не могли бы вы рассказать нам что-нибудь о фазе uv__run_prepare
?
5. В каком режиме по умолчанию работает цикл обработки событий? К сожалению, никакой информации об этом здесь я не нахожу. Какой из них наиболее эффективен для приложений Node.js? Или это зависит?
Большое спасибо за ваше время!