Дочерний процесс node.js - разница между spawn и fork


147

Это может показаться простым вопросом, но мне не удалось найти никакой документации:

В чем разница между разветвлением и порождением процесса node.js? Я читал, что разветвление - это особый случай нереста, но каковы различные варианты использования / варианты использования каждого из них?

Ответы:


221

Spawn - это команда, предназначенная для запуска системных команд. Когда вы запускаете spawn, вы отправляете ему системную команду, которая будет запускаться в собственном процессе, но не будет выполнять никакого дополнительного кода в процессе вашего узла. Вы можете добавить слушателей для порожденного вами процесса, чтобы ваш код мог взаимодействовать с порожденным процессом, но новый экземпляр V8 не создается (если, конечно, ваша команда не является другой командой Node, но в этом случае вы должны использовать fork!) И на процессоре активна только одна копия вашего узлового модуля.

Fork - это особый экземпляр spawn, который запускает новый экземпляр двигателя V8. Это означает, что вы можете создать несколько воркеров, работающих на одной и той же кодовой базе Node, или, возможно, в другом модуле для конкретной задачи. Это наиболее полезно для создания пула рабочих. Хотя модель асинхронных событий узла позволяет достаточно эффективно использовать одно ядро ​​машины, она не позволяет процессу узла использовать многоядерные машины. Самый простой способ добиться этого - запустить несколько копий одной и той же программы на одном процессоре.

Хорошее эмпирическое правило - от одного до двух узловых процессов на ядро, возможно, больше для машин с хорошим соотношением тактовой частоты оперативной памяти и тактовой частоты процессора, или для узловых процессов, которые сильно загружают ввод-вывод и мало работают с процессором, чтобы минимизировать время простоя события цикл ждет новых событий. Однако последнее предложение представляет собой микрооптимизацию и потребует тщательного тестирования, чтобы убедиться, что ваша ситуация соответствует потребностям многих процессов / ядра. Фактически вы можете снизить производительность, создав слишком много воркеров для вашей машины / сценария.

В конце концов, вы можете использовать spawn так же, как описано выше, отправив spawn команду Node. Но это было бы глупо, потому что fork делает некоторые вещи для оптимизации процесса создания экземпляров V8. Просто поясняю, что в конечном итоге spawn включает вилку. Fork оптимален для этого конкретного и очень полезного варианта использования.

http://nodejs.org/api/child_process.html#child_process_child_process_exec_command_options_callback


@ChrisCM, если я использую, скажем, var child = require('child_process').fork('child.js');например, в моем основном приложении, у меня теперь будет работать 2 отдельных ядра. Если бы мне пришлось запустить тяжелый цикл for в child.js (процессе), я бы, по сути, использовал больше ядер для работы child.js, верно? Будет ли это использование процессора влиять на мое основное ядро ​​приложения?
NiCk Newman

2
Невозможно сделать что-либо на CPU, не влияя на другие вещи. Планирование, использование общего кэша, трафик ШИНЫ и т. Д. Однако он должен использовать преимущества отдельного ядра и ВСЕГО не затрагивается ваш основной цикл выполнения. То есть, это не те серьезные негативные эффекты, которых можно ожидать от двух процессов, работающих на одном и том же одноядерном процессоре. На данный момент правильная оптимизация зависит от операционной системы и настройки оборудования. Различные настройки могут дать разные результаты.
ChrisCM

@ChrisCM Да, я использую глобальный MonsterLoop для синхронизации позиционирования монстров, и этот объект, который он выполняет, может иметь до 5000 ключей. Я повторяю его каждые 2 секунды, и кажется, что он сокращает использование сотен памяти моего процессора (основная игра). Я бы предпочел сделать это таким образом, вместо того, чтобы кластеризовать этот цикл и заставлять его запускать xx раз на каждое ядро, которое у меня было ... Тай для вашего понимания ~ Теперь я просто не знаю, следует ли мне использовать Redis или внутренний IPC: P
NiCk Newman

2
Спасибо за ответ «почему» - во всех сообщениях, которые я читал до этого, пропущена эта простая часть объяснения.
aaaaaa

@ChrisCM В вашем ответе "..но не выполняет никакого дальнейшего кода в процессе вашего узла ..". Означает ли это, что основной поток ожидает и ничего не обрабатывает .. Если ДА, то какой смысл использовать здесь spawn?
Абхи

11

TL; DR

Spawn

Когда мицелий создаются - Это создает потоковый интерфейс между родительским и дочерним процессом.

средства потокового интерфейса - буферизация данных в двоичном формате вONE TIME

Fork

Когда вилка создаются - Это создает канал связи между родителем и ребенком процессом

средства канала связи - обмен сообщениями

Difference

Ну, оба выглядят как будто выполняют одинаковую передачу данных , за исключением разницы ниже

spawn будет полезен, когда вы хотите сделать непрерывный буфер данных в двоичном формате / формате кодирования , например - передать 1 ГБ видеофайла, изображения, файлов журнала вONE TIME

fork будет полезен, когда вы хотите отправлять сообщения, например, JSONили XMLобмен данными

Conslusion

spawn следует использовать для потоковой передачи больших данных / файлов / изображений ОТ процесса spawn К родительскому процессу

fork следует использовать для обмена сообщениями Json / Xml.

  • Например, предположим, что от родителя создано 10 процессов форка.
  • и каждый процесс выполняет некоторую операцию
  • и каждый процесс по завершении операции отправит сообщение родительскому « процесс № 4 выполнен », « процесс № 8 выполнен »

А как насчет непрерывной записи данных от родителя к потомку и, наконец, внутри файла?
Esqarrouth

1
@Esqarrouth, вам нужно определить, будет ли это непрерывный поток или сообщения. И вы использовали слово «непрерывное ведение журнала», я полагаю, вы будете писать журналы (JSON) для дочернего элемента. Если да, то используйте FORKelse, если у вас есть очень большой кусок данных для буферизации, тогда используйтеSPAWN
vijay

5
  • spawn - child_process.spawn запускает новый процесс с заданной командой.
  • fork - Метод child_process.fork является частным случаем spawn () для создания дочерних процессов.

Метод spawn ()

Метод child_process.spawn запускает новый процесс с заданной командой. Он имеет следующую подпись -

child_process.spawn(command[, args][, options])

Узнать больше о вариантах

Метод spawn () возвращает потоки (stdout и stderr), и его следует использовать, когда процесс возвращает объемный объем данных. spawn () начинает получать ответ, как только процесс начинает выполняться.

Метод fork ()

Метод child_process.fork является частным случаем spawn () для создания процессов Node. Он имеет следующую подпись -

 child_process.fork(modulePath[, args][, options])

Метод fork возвращает объект со встроенным каналом связи в дополнение к наличию всех методов в обычном экземпляре ChildProcess.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.