Как работает Nodejs internal threadpool?

Я прочитал много статей о том, как работает NodeJs. Но я до сих пор не могу понять, как внутренние потоки Nodejs выполняют операции ввода-вывода.

В этом ответе qaru.site/info/497829/... он сказал, что для обработки операций ввода-вывода есть 4 внутренних потока в пуле потоков NodeJs. Итак, что, если у меня есть 1000 запросов, поступающих в одно и то же время, каждый запрос хочет выполнять операции ввода-вывода, такие как извлечение огромных данных из базы данных. NodeJs доставляет этот запрос этим 4 рабочим потокам, соответственно, без блокировки основного потока. Таким образом, максимальное количество операций ввода-вывода, которые NodeJs может обрабатывать одновременно, - это 4 операции. Я не прав?.

Если я прав, где будут обрабатываться остальные запросы?. Основной единственный поток не блокирует и продолжает вести запрос к соответствующим операторам, поэтому, где эти запросы будут отправляться, пока весь рабочий поток будет заполнен задачей?,

На приведенном ниже изображении все внутренние рабочие потоки полны заданий, предполагая, что всем им необходимо извлечь много данных из базы данных, а основной отдельный поток будет продолжать новые запросы к эти рабочие, куда будут отправляться эти просьбы? У него есть внутренняя задача для хранения этих запросов?

enter image description here

Ответ 1

Единственный пул потоков для каждого процесса, предоставляемый libuv, по умолчанию создает 4 потока. Переменная среды UV_THREADPOOL_SIZE может использоваться для изменения количества потоков, созданных при запуске процесса node, до максимального значения 128.

Когда все эти потоки заблокированы, дальнейшие запросы на их использование ставятся в очередь. Метод API для запроса потока называется uv_queue_work.

Этот пул потоков используется для любых системных вызовов, которые приведут к блокировке IO, которая включает операции локальной файловой системы. Он также может использоваться для уменьшения эффекта интенсивных операций ЦП, как отмечает @Andrey.

Неблокирующий IO, поддерживаемый большинством сетевых операций, не должен использовать пул потоков.

Если исходный код используемого драйвера базы данных доступен, и вы можете найти ссылку на uv_queue_work, то он, вероятно, использует пул потоков.

Документация libuv thread pool содержит дополнительные технические детали, если требуется.

Ответ 2

нет, основной вариант использования пула потоков - это разгрузка интенсивных операций ЦП. IO выполняется в одном потоке - вам не нужно несколько потоков, если вы ожидаете внешние данные параллельно, а цикл событий - это точно метод организации потока выполнения, чтобы вы ждали как можно больше параллельно

Пример: Вам нужно отправить 100 писем с вопросом (y/n), а другой - с номером ответа "y". Требуется около 30 секунд для написания электронной почты и в среднем два часа для ответа + 10 секунд для чтения ответа. Вы начинаете с написания всех 100 писем (50 минут времени), затем вы ждете сигнала тревоги, который будит вас каждый раз, когда приходит ответ, и по мере получения ответов вы увеличиваете количество "y". через ~ 2 часа и 50 минут вы закончите. Это пример async IO и цикла событий (без пулов потоков)

Пример блокировки: отправьте письмо, подождите ответа, повторите. Делает 4 дня (два, если вы можете клонировать другого)

Пример пула асинхронных потоков: каждый ответ на языке, который вы не знаете. У вас 4 друзей-переводчика. Вы отправляете им текст по электронной почте, и они отправляют вам текст, переведенный по электронной почте (или, более точно: вы печатаете текст и помещаете его в папку "нуждается в переводе". Всякий раз, когда доступен переводчик, текст извлекается из папки)