js专题:Node多进程源码总结
-
exec和execFile到底有什么区别
-
为什么exec/execFile/fork都是通过spawn实现的,spawn的作用到底是什么
在 Node.js中,exec、execFile和fork都是通过spawn实现的,这主要是因为spawn是创建子进程的基础函数,提供了最底层的接口。spawn的主要作用是异步执行一个命令,并返回一个表示该命令的子进程对象
-
为什么spawn调用后没有回调,而exec和execFile能够回调
设计目标不同: spawn 提供的是流式接口,适合于处理大量输出或长时间运行的进程;而 exec 和 execFile 提供的是一次性获取输出的接口,适合于执行简单命令或需要快速获取输出的情况。
回调机制不同: 由于设计目标的不同,spawn 不提供回调机制,而是通过事件来处理子进程的输出和结束事件;而 exec 和 execFile 则通过回调函数来一次性地获取输出。
-
为什么spawn调用后需要手动调用child.stdout.on(‘data’, callback),这里的child.stdout / child.stderr到底是什么
在 Node.js中,当使用spawn方法创建一个子进程时,该方法会返回一个ChildProcess对象。这个对象代表了新创建的子进程,并且提供了与之交互的接口。child.stdout和child.stderr是这个ChildProcess对象的两个重要属性,它们分别代表了子进程的标准输出和标准错误输出。
当使用spawn创建子进程时,子进程的输出不会自动地传递给父进程或以任何方式缓冲起来。相反,Node.js提供了流式接口,允许通过监听child.stdout和child.stderr上的data事件来逐块地处理子进程的输出。
-
为什么有data/error/exit/close这么多种回调,它们的执行顺序到底是怎样的
在 Node.js中,使用spawn方法创建子进程时,会涉及多个事件来处理子进程的输出和状态变化。这些事件包括data、error、end(对于流)、exit(对于子进程)以及close(既适用于流也适用于子进程)。
事件及其作用
1. data事件:当子进程的标准输出(stdout)或标准错误输出(stderr)有新的数据块可用时触发。允许你逐块处理子进程的输出。
2. error事件:在读取子进程输出时发生错误时触发。需要添加错误处理逻辑以避免程序崩溃。
3. end事件(流级别):当子进程的标准输出或标准错误输出流中没有更多数据可读时触发。表示子进程已经完成了该流的输出。
4. exit事件(子进程级别):当子进程退出时触发。提供了一个退出码,用于判断子进程是如何结束的。
5. close事件:
流级别:当子进程的标准输出或标准错误输出流被关闭时触发。通常发生在end事件之后。
子进程级别:当子进程的所有I/O流(包括stdout和stderr)都关闭时触发。标志着子进程已经完全结束。
事件执行顺序的一般规律
data事件:随着子进程的输出不断生成,data事件可能会多次触发。
error事件:如果在读取输出时发生错误,会立即触发 error 事件。
end事件(流级别):当子进程完成某个流的输出时,会触发该流的 end 事件。
close事件(流级别):随后,当该流的文件描述符被关闭时,会触发 close 事件。
exit事件:当子进程退出时,会触发 exit 事件,提供一个退出码。
close事件(子进程级别):最后,当子进程的所有 I/O 流都关闭时,会触发子进程级别的 close 事件。
-
exec/execFile/spawn/fork的区别
exec:原理是调用 /bin/sh -c 执行我们传入的 shell 脚本,底层调用了 execFile
execFile:原理是直接执行我们传入的 file 和 args,底层调用 spawn 创建和执行子进程,并建立了回调,一次性将所有的 stdout 和 stderr 结果返回
spawn:原理是调用了 internal/child_process,实例化了 ChildProcess 子进程对象,再调用 child.spawn 创建子进程并执行命令,底层是调用了 child._handle.spawn 执行 process_wrap 中的 spawn 方法,执行过程是异步的,执行完毕后通过 PIPE 进行单向数据通信,通信结束后会子进程发起 onexit 回调,同时 Socket 会执行 close 回调
fork:原理是通过 spawn 创建子进程和执行命令,采用 node 执行命令,通过 setupchannel 创建 IPC 用于子进程和父进程之间的双向通信
-
data/error/exit/close回调的区别
data:主进程读取数据过程中通过 onStreamRead 发起的回调
error:命令执行失败后发起的回调
exit:子进程关闭完成后发起的回调
close:子进程所有 Socket 通信端口全部关闭后发起的回调
stdout close/stderr close:特定的 PIPE 读取完成后调用 onReadableStreamEnd 关闭 Socket 时发起的回调
夜雨聆风
