📜  Node.js子进程(1)

📅  最后修改于: 2023-12-03 15:17:57.464000             🧑  作者: Mango

Node.js子进程

什么是子进程

子进程是指在父进程之下运行的进程。在Node.js中,子进程可以通过 "child_process" 模块实现。

在一些需要运行耗时的或者占用资源的应用中,我们可能需要使用子进程来进行分散计算或者资源分配。此时,Node.js的子进程模块就变得尤为重要。

child_process模块

Node.js的child_process模块提供了四个不同的函数来创建子进程:

  • spawn :创建一个新的进程,该进程从指定的命令行参数中产生。
  • exec :使用shell来执行命令,当命令的运行结果很大时,使用它比较好。
  • execFile :像child_process.exec()一样执行外部程序,但是直接衍生出新的进程,而不创建shell进程。
  • fork :特殊的spawn(),用于在子进程中启动Node.js进程。
示例
spawn函数

spawn是一个异步函数,我们可以通过回调函数来获得它的输出结果,如下所示:

const { spawn } = require('child_process');
const ls = spawn('ls', ['-lh', '/usr']);

ls.stdout.on('data', (data) => {
  console.log(`stdout: ${data}`);
});

ls.stderr.on('data', (data) => {
  console.error(`stderr: ${data}`);
});

ls.on('close', (code) => {
  console.log(`child process exited with code ${code}`);
});

在上面的例子中,我们使用spawn函数创建了一个名为ls的子进程,使用参数['-lh', '/usr'] 来运行 'ls -lh /usr' 命令。然后监听 stdout 和 stderr 的 'data' 事件,以便处理它们的输出。最后,我们通过处理 'close' 事件来确定进程的退出码。

exec函数

exec函数通过shell来执行命令,因此它比spawn函数更灵活,但是对于大量输出而言,它的性能可能不如spawn函数。

下面是exec函数的示例代码:

const { exec } = require('child_process');

exec('ls -lh /usr', (error, stdout, stderr) => {
  if (error) {
    console.error(`exec error: ${error}`);
    return;
  }
  console.log(`stdout: ${stdout}`);
  console.error(`stderr: ${stderr}`);
});

在上面的例子中,我们使用exec函数来执行命令 'ls -lh /usr',回调函数中包含了命令的标准输出和标准错误输出的数据流。

execFile函数

execFile用于执行外部程序,直接衍生出新的进程,而不创建shell进程。下面是一个例子:

const { execFile } = require('child_process');
const child = execFile('node', ['--version'], (error, stdout, stderr) => {
  if (error) {
    throw error;
  }
  console.log(stdout);
});

在上面的例子中,我们使用execFile函数来执行node命令,参数中传入 '--version' 参数。当命令执行完成后,我们会收到它的输出结果。

fork函数

父进程通过 fork 函数来创建子进程,子进程是一个 Node.js 进程。我们使用了与 child_process.spawn() 相同的函数签名。

下面是一个例子:

const { fork } = require('child_process');
const child = fork('./child.js');
child.on('message', (msg) => {
  console.log('Message from child', msg);
});
child.send({ hello: 'world' });

在上面的例子中,我们 fork 了一个名为 child 的子进程,使用了 './child.js' 脚本。然后,我们在父进程中监听 'message' 事件,以便在子进程中收到消息时能够处理它们。最后,我们通过 child.send 来向子进程发送消息。