Node.js - единственный поток, не блокирующий?

Я изучаю Node.js, и я прочитал, что Node.js однопоточный и неблокирующий.

У меня хороший фон в JavaScript, и я действительно понимаю обратные вызовы, но я действительно не понимаю, как Node.js может быть однопоточным и запускать код в фоновом режиме. Разве это не противоречит?

Потому что, если Node.js однопоточный, он все равно может выполнять только одну задачу в то время. Итак, если он что-то работает в фоновом режиме, он должен остановить текущую задачу, чтобы обработать что-то в фоновом режиме, правильно?

Как это работает практически?

Ответы

Ответ 1

То, что "в фоновом режиме" действительно означает с точки зрения NodeJS, состоит в том, что на этот раз все будет помещено в список todo. Всякий раз, когда Node выполняется с тем, что он делает, он выбирает из верхней части списка задач. Вот почему делать то, что на самом деле блокирует, может повредить ваш день. Все, что происходит "в фоновом режиме" (на самом деле просто ждет в списке задач), останавливается до завершения задачи блокировки.

Ответ 2

Lucas объяснил это хорошо, но я хотел бы добавить, что можно добавить "узлы" через некоторые библиотеки кластеров, если вы хотите использовать преимущества своих процессоров.

Учебник для кластера: http://blog.carbonfive.com/2014/02/28/taking-advantage-of-multi-processor-environments-in-node-js/

Некоторые хостеры предоставят вам опции "масштабируемости", например Heroku

В любом случае, когда вы используете MongoDB с помощью NodeJS (например, через Mongoose), он создает множественные соединения.

ПРИМЕЧАНИЕ. Преимущество, которое должно быть односторонним, - обрабатывать миллионы пользователей. С устаревшим многопоточным сервером (apache) вы создаете поток для пользователя EACH, тогда вам нужны действительно БОЛЬШИЕ серверы для обработки тысяч людей.

Ответ 3

В то время как движок JavaScript монопоточен, существует несколько потоков "в фоновом режиме", которые имеют дело со всеми неблокирующими ввода-выводами.

В частности, libuv имеет пул рабочих потоков, ожидающих событий ОС, сигналов ввода-вывода, кода на С++ и т.д. Размер этого пула определяется переменной среды UV_THREADPOOL_SIZE.

Никакой код JavaScript никогда не запускается "в фоновом режиме". Функции JavaScript (т.е. Обратные вызовы) планируется запустить позже в главном цикле событий либо другими функциями JS, либо непосредственно сотрудниками libuv. Если цикл заблокирован, все запланированные должны ждать его.

Ответ 4

На самом деле, Node.js не является точно односторонним. Node.js используют один "основной поток", который является потоком, в котором выполняется script. Этот основной поток никогда не должен блокироваться. Таким образом, длительные операции выполняются в отдельных потоках. Например, Node.js использует библиотеку libuv, которая поддерживает пул потоков, используемых для выполнения операций ввода-вывода.