processo filho node.js - diferença entre spawn e fork

141

Isso pode parecer uma pergunta básica, mas não consegui encontrar nenhuma documentação:

Qual é a diferença entre bifurcar e gerar um processo node.js? Eu li que a bifurcação é um caso especial de desova, mas quais são os diferentes casos de uso / rejeições para usar cada um deles?

Hitesh
fonte

Respostas:

215

Spawn é um comando projetado para executar comandos do sistema. Ao executar o spawn, você envia um comando do sistema que será executado em seu próprio processo, mas não executa nenhum código adicional no processo do nó. Você pode adicionar ouvintes para o processo gerado, para permitir que seu código interaja com o processo gerado, mas nenhuma nova instância da V8 é criada (a menos que seu comando seja outro comando Node, mas nesse caso você deve usar o fork!) E apenas uma cópia do seu módulo de nó está ativa no processador.

Fork é uma instância especial de spawn, que executa uma nova instância do mecanismo V8. Ou seja, você pode essencialmente criar vários trabalhadores, executando exatamente a mesma base de código do Nó ou talvez um módulo diferente para uma tarefa específica. Isso é mais útil para criar um pool de trabalhadores. Embora o modelo de evento assíncrono do nó permita que um único núcleo de uma máquina seja usado com bastante eficiência, ele não permite que um processo do nó faça uso de máquinas com vários núcleos. A maneira mais fácil de fazer isso é executar várias cópias do mesmo programa, em um único processador.

Uma boa regra geral é de um a dois processos de nó por núcleo, talvez mais para máquinas com uma boa taxa de clock de ram / CPU, ou para processos de nó pesados ​​em E / S e leves em trabalho da CPU, para minimizar o tempo de inatividade do evento O loop está aguardando novos eventos. No entanto, a última sugestão é uma micro-otimização e precisaria de um benchmarking cuidadoso para garantir que sua situação atenda à necessidade de muitos processos / núcleo. Você pode realmente diminuir o desempenho gerando muitos trabalhadores para sua máquina / cenário.

Por fim, você pode usar o spawn de uma maneira que fez acima, enviando ao spawn um comando Node. Mas isso seria bobagem, porque o fork faz algumas coisas para otimizar o processo de criação de instâncias V8. Apenas para esclarecer, a desova envolve garfo. O garfo é ideal para este caso de uso específico e muito útil.

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

ChrisCM
fonte
@ ChrisCM, se eu usar, digamos, var child = require('child_process').fork('child.js');por exemplo, no meu aplicativo principal, agora terei dois núcleos separados em execução. Se eu executasse um loop for pesado no child.js (processo), estaria essencialmente utilizando mais núcleos para alimentar o child.js, certo? No entanto, esse uso da CPU afetaria meu núcleo principal de aplicativos?
NiCk Newman
2
É impossível fazer qualquer coisa em uma CPU sem afetar outras coisas. Agendamento, uso de cache compartilhado, tráfego BUS, etc. No entanto, ele deve tirar proveito de um núcleo separado e deixar o ciclo de execução principal MUITO MAIS inalterado. Como não, os graves efeitos negativos que você esperaria de ter dois processos em execução no mesmo processador de núcleo único. Neste ponto, depende realmente do sistema operacional e da configuração do hardware otimizar adequadamente. Diferentes configurações podem gerar resultados diferentes.
ChrisCM 03/09/2015
@ChrisCM Sim, eu uso um MonsterLoop global para sincronizar o posicionamento de monstros e o objeto iterado pode ter até 5.000 chaves. Eu repito a cada 2 segundos e bifurcando parece que está destruindo centenas de uso de memória da minha CPU (jogo principal). Eu preferiria fazê-lo desta maneira, em vez de agrupar esse loop e fazê-lo executar xx uma quantidade de vezes por núcleo que eu tinha ... Ty para sua percepção ~ Agora, eu simplesmente não sei se devo usar o Redis ou o IPC interno: P
NiCk Newman
2
Obrigado por abordar o "porquê" - todas as postagens que li até esta perderam essa parte simples da explicação.
aaaaaa
@ChrisCM Na sua resposta "..mas não executa nenhum código adicional no processo do seu nó ..". Isso significa que o thread principal está aguardando e não está processando nada ... Se SIM, qual é a utilidade de usar spawn aqui ..?
Abhi 15/03
9

TLDR

Spawn

Quando um spawn é criado - ele cria uma interface de streaming entre o processo pai e filho.

meios de interface de streaming - buffering de dados em formato binário emONE TIME

Fork

Quando um fork é criado - cria um canal de comunicação entre o processo pai e filho

meios de canal de comunicação - mensagens

Difference

Bem, ambos parecem fazer a mesma transferência de dados , exceto a diferença abaixo

O spawn será útil quando você quiser fazer um buffer de dados contínuo no formato binário / de codificação , por exemplo - Transferir arquivo de vídeo de 1 gb, imagem, arquivos de logONE TIME

O fork será útil quando você desejar enviar mensagens, por exemplo - JSONou XMLmensagens de dados

Conslusion

desova deve ser usado para streaming de grandes dados / arquivos / imagens de desova processo para pai processo

fork deve ser usado para fazer mensagens Json / Xml.

  • Por exemplo, suponha que 10 processos de fork sejam criados a partir do pai.
  • e cada processo executa alguma operação
  • e cada processo ao concluir a operação enviará uma mensagem para o pai ' processo no.4 concluído ', ' processo no.8 concluído '
vijay
fonte
E os dados de registro contínuo do pai em um filho e, finalmente, dentro de um arquivo?
Esqarrouth 11/04
1
@Esqarrouth, você precisa identificar se será um fluxo contínuo ou mensagens. E você usou a palavra "loging contínua" eu acredito u será wrting de logs (JSON) para criança, Se sim, então use FORKoutra coisa se você tiver muito grande bloco de dados a ser BUFFERED então usarSPAWN
Vijay
5
  • spawn - child_process.spawn inicia um novo processo com um determinado comando.
  • fork - O método child_process.fork é um caso especial do spawn () para criar processos filhos.

O método spawn ()

O método child_process.spawn inicia um novo processo com um determinado comando. Possui a seguinte assinatura -

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

Leia mais sobre as opções

O método spawn () retorna fluxos (stdout & stderr) e deve ser usado quando o processo retornar uma quantidade de dados em volume. spawn () começa a receber a resposta assim que o processo começa a ser executado.

O método fork ()

O método child_process.fork é um caso especial de spawn () para criar processos de Nó. Possui a seguinte assinatura -

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

O método fork retorna um objeto com um canal de comunicação interno, além de ter todos os métodos em uma instância normal do ChildProcess.

Igor Litvinovich
fonte