Чтобы понять, что здесь происходит, вы должны понять несколько вещей о цикле событий узла, а также об ОС и ЦП.
Прежде всего, давайте лучше разберем этот код.Вы называете это рекурсивным, но так ли это?
В рекурсии мы обычно думаем о вложенных стеках вызовов, а затем, когда вычисления выполнены (достигают базового случая), стек "раскручивается" обратно к точке, где нашбыла вызвана рекурсивная функция.
Хотя этот метод вызывает сам себя (косвенно через обратный вызов), цикл событий искажает то, что происходит на самом деле.
process.nextTick принимает функцию какобратный вызов и ставит его первым в списке вещей, которые будут сделаны на следующем цикле обработки событий.Затем выполняется этот обратный вызов, и когда он завершается, вы снова регистрируете тот же самый обратный вызов.По сути, ключевое различие между этой и настоящей рекурсией заключается в том, что наш стек вызовов никогда не получает более одного глубокого вызова.Мы никогда не «раскручиваем» стек, у нас просто есть множество маленьких коротких стеков подряд.
Хорошо, так почему это важно?
Когда мы лучше понимаем цикл событий и то, что на самом деле происходит, мы можем лучше понять, как используются системные ресурсы.Используя process.nextTick таким образом, вы гарантируете, что ВСЕГДА что-то нужно делать в цикле обработки событий, поэтому вы получаете высокую загрузку ЦП (но вы уже знали об этом).Теперь, если предположить, что ваш HTTP-сервер должен запускаться в одном и том же процессе в качестве сценария, как показано ниже
function interval(){
process.nextTick(doIntervalStuff)
}
function doIntervalStuff() {
someSmallSyncCode();
interval();
}
http.createServer(function (req, res) {
doHTTPStuff()
}).listen(1337, "127.0.0.1");
, то как разделить использование ЦП между двумя разными частямипрограмма?Ну, это сложно сказать, но если мы понимаем цикл событий, мы можем, по крайней мере, догадаться.
Поскольку мы используем process.nextTick, функция doIntervalStuff будет запускаться каждый раз при «запуске» цикла событийоднако, если что-то нужно сделать для HTTP-сервера (например, обработать соединение), то мы знаем, что это будет сделано до следующего запуска цикла событий, и помним, что из-за четного характера узла это может бытьобработка любого количества соединений на одной итерации цикла событий.Это подразумевает, что, по крайней мере, теоретически каждая функция в процессе получает то, что ей «нужно» в части использования ЦП, а затем функции process.nextTick используют остальное.Хотя это не совсем верно (например, ваш кусочек блокирующего кода может испортить это), это достаточно хорошая модель, чтобы подумать.
Хорошо, теперь (наконец-то) к вашему реальному вопросу, чтопро отдельные процессы?
Интересно, что ОС и ЦП часто бывают очень «равномерными» по своей природе.Всякий раз, когда процесс хочет что-то сделать (например, в случае узла, запустить итерацию цикла событий), он делает запрос к обрабатываемой ОС, ОС затем помещает это задание в готовую очередь (которая имеет приоритет)и он выполняется, когда планировщик ЦП решает обойти его.Это опять-таки упрощенная модель, но основная концепция, которую нужно убрать, очень похожа на цикл обработки событий узла, каждый процесс получает то, что ему «нужно», а затем такой процесс, как приложение вашего узла, пытается выполнить, когда это возможно, заполняяпромежутки.
Таким образом, когда процессы вашего узла говорят, что он берет 100% процессорного времени, это не совсем точно, иначе больше ничего не будет сделано, и система рухнет.По сути, он занимает весь процессор, который может, но ОС по-прежнему определяет другие элементы для вставки.
Если бы вы добавили процесс второго узла, который выполнял тот же процесс.nextTick, ОС постаралась бы приспособитьсяоба процесса и, в зависимости от объема работы, выполняемой в цикле обработки событий каждого узла, ОС будет соответствующим образом разделять работу (по крайней мере, теоретически, но в действительности, вероятно, просто приведет к замедлению всего и нестабильности системы).
Еще раз, это очень упрощенно, но, надеюсь, это даст вам представление о том, что происходит.Тем не менее, я бы не рекомендовал использовать process.nextTick, если вы не знаете, что он вам нужен, если делать что-то каждые 5 мс приемлемо, используя setTimeout вместо process.nextTick сэкономит кучу ресурсов при использовании процессора.
Надеюсь, что ответит на ваш вопрос: D