node.js子进程-生成和派生之间的区别


141

这似乎是一个基本问题,但是我找不到任何文档:

分叉和生成node.js进程有什么区别?我已经读过分叉是生成的一种特例,但是使用它们的不同用例/重用分别是什么?

Answers:


215

Spawn是用于运行系统命令的命令。运行spawn时,会向其发送系统命令,该命令将在其自己的进程上运行,但不会在节点进程中执行任何其他代码。您可以为生成的进程添加侦听器,以允许您的代码与生成的进程进行交互,但是不会创建新的V8实例(除非您的命令是另一个Node命令,但是在这种情况下,您应该使用fork!)和您的节点模块只有一个副本在处理器上处于活动状态。

Fork是spawn的特殊实例,它运行V8引擎的新实例。意思是,您实际上可以创建多个工作程序,它们在完全相同的Node代码库上运行,或者为特定任务运行在不同的模块上。这对于创建工作池最有用。尽管节点的异步事件模型允许相当高效地使用机器的单个核心,但它不允许节点进程使用多核心机器。实现此目的最简单的方法是在单个处理器上运行同一程序的多个副本。

一个好的经验法则是每个内核一到两个节点进程,对于具有良好的内存时钟/ cpu时钟比率的机器,或者对于I / O繁重且CPU工作轻的节点进程,也许更多,以最大程度地减少事件的停机时间。循环正在等待新事件。但是,后一种建议是微优化,因此需要仔细进行基准测试,以确保您的情况适合许多流程/核心的需求。您实际上可以通过为计算机/方案生成过多的工作程序来降低性能。

最终,您可以通过发送spawn一个Node命令,以上述方式使用spawn。但这很愚蠢,因为fork做了一些事情来优化创建V8实例的过程。只需说清楚,最终生成就包含了fork。对于这种特殊且非常有用的用例,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个独立的内核在运行。如果我要在child.js(进程)中运行繁重的 for循环,那么我实质上将利用更多内核来增强child.js的功能,对吗?cpu的使用会影响我的主应用程序内核吗?
NiCk Newman

2
如果不影响其他事情,就不可能在CPU上做任何事情。调度,共享缓存使用率,BUS流量等。但是,它应该利用独立的内核,并且不会使主运行循环受影响。就像这样,在同一个单核处理器上运行两个进程不会产生严重的负面影响。在这一点上,真正取决于操作系统和硬件设置来进行适当的优化。不同的设置可能会产生不同的结果。
ChrisCM 2015年

@ChrisCM是的,我使用了一个全局MonsterLoop来同步怪物的定位,并且它迭代的对象可以多达5,000个键。我每2秒钟进行一次遍历,然后分叉,好像它正在减少CPU上数百个内存的使用(主要游戏之一)。我宁愿这样做,而不是集群化循环并使之在每个内核中运行xx倍。。。Ty为您提供了见识〜现在我不知道是否应该使用Redis或内部IPC: P
NiCk Newman

2
感谢您解决“为什么”的问题-我读到这篇文章的所有帖子都忽略了解释的简单部分。
aaaaaa

@ChrisCM在您中回答“ ..但不会在节点进程中执行任何其他代码。”。这是否意味着主线程正在等待并且什么都不处理。如果是,那么在这里使用spawn有什么用?
阿比(Abhi)

9

TLDR

Spawn

产卵创建- 它创建了一个流媒体接口,父母和孩子之间的过程。

流接口工具 -以二进制格式缓冲数据ONE TIME

Fork

创建-它创建了一个通信信道的父进程和子进程之间

通讯渠道手段 -消息传递

Difference

好吧,两者看起来都在做相同的数据传输,除了下面的区别

当您要以二进制/编码格式进行连续数据缓冲时,spawn会很有用,例如-传输1gb的视频文件,图像,日志文件ONE TIME

,当你想要做的将是有益的短信 如- JSONXML数据消息

Conslusion

spawn应该用于从spawn进程到进程 流式传输大数据/文件/图像

应该使用fork来进行Json / Xml消息传递。

  • 例如,假设从父级创建了10个fork过程。
  • 每个过程执行一些操作
  • 并且每个完成操作的进程都会向父进程发送消息“ 第4个进程已完成 ”,“第8个进程已完成

从父级到子级并最终在文件中连续记录数据该怎么办?
Esqarrouth

1
@Esqarrouth,您需要确定它是连续流还是消息。而且您使用了“连续日志记录”一词,我相信您会把logs(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实例中之外,还返回带有内置通信通道的对象。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.