Skip to content

你需要知道的Node.js Child Processes #15

Description

@hawx1993

创建Node子进程的方式

node.js提供了child_process模块,通过多进程来实现对多核CPU的利用.child_process模块提供了四个创建子进程的函数,分别是spawn()exec()execFile()fork()

每个子进程可以获取三个标准的stdio流,我们可以使用child.stdinchild.stdoutchild.stderr访问它们。

  • exec()execFile()fork()底层都是通过spawn()实现的。
  • exec()execFile()额外提供了回调,当子进程停止的时候执行。

child_process.exec():是“同步中的异步”, 它要等到子进程运行结束以后然后一次性返回所有的buffer数据。衍生一个 shell 并在 shell 上运行一个命令,当完成时会传入 stdout 和 stderr 到一个回调。

child_process.spawn是“异步中的异步”,会返回一个带有stdout和stderr流的对象,在子线程开始执行后,就开始不断将数据从子进程返回给主进程。

child_process.spawn(command[, args][, options])
child_process.exec(command[, options][, callback])
child_process.execFile(file[, args][, options][, callback])
child_process.fork(modulePath[, args][, options])

总结一下:当你想要从子进程返回大量数据时使用spawn,如果只是返回简单的状态信息,那么使用exec。

  • spwan
var child_process = require('child_process');
var child = child_process.spawn( command );
    child.stdout.on('data', function(data) {
      console.log(data);
});
  • exec和execSync
var child_process = require('child_process');
child_process.exec( command , function(err, stdout , stderr ) {
  console.log( stdout );
});

image

execSync是exec的同步执行版本。

image

  • execFile
var child_process = require('child_process');
child_process.execFile( file , function(err, stdout , stderr ) {
  console.log( stdout );
});
  • fork
    fork函数可直接运行Node.js模块,所以我们可以直接通过指定模块路径而直接进行操作。与spawn方法不同的是,fork会在父进程与子进程之间,建立一个通信管道,用于进程之间的通信。
var child_process = require('child_process');
child_process.fork( modulePath );

image

使用 child_process.fork() 生成新进程之后,就可以用 child.send(message, [sendHandle]) 向新进程发送消息。新进程中通过监听message事件,来获取消息。

异步 vs 同步

大部分时候,子进程的创建是异步的。也就是说,它不会阻塞当前的事件循环,这对于性能的提升很有帮助。

当然,有的时候,同步的方式会更方便(阻塞事件循环),比如通过子进程的方式来执行shell脚本时。

node同样提供同步的版本,比如:
来自child_process模块​​的函数spawn,exec和execFile具有同步阻止的版本:

const { 
  spawnSync, 
  execSync, 
  execFileSync,
} = require('child_process');

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions