2015-04-02 3 views
11

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

В этом ответе https://stackoverflow.com/a/20346545/1813428 он сказал, что в пуле потоков NodeJs имеется 4 внутренних потока для обработки операций ввода-вывода. Итак, что, если у меня есть 1000 запросов, поступающих в одно и то же время, каждый запрос хочет выполнять операции ввода-вывода, такие как извлечение огромных данных из базы данных. NodeJs доставляет этот запрос этим 4 рабочим потокам, соответственно, без блокировки основного потока. Таким образом, максимальное количество операций ввода-вывода, которые NodeJs может обрабатывать одновременно, - это 4 операции. Я ошибаюсь?.

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

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

enter image description here

+0

Насколько вам комфортно с C или C++? – slebetman

ответ

9

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

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

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

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

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

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

+0

очень полезный ответ – xtiger

1

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

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

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

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