Node.js中创建和管理外部进程详解(4)


var spawn = require('child_process').spawn;
// 生成一个子进程来执行+1应用
var child = spawn('node', ['plus_one.js']);
// 每一秒调用一次函数
setInterval(function() {
    // Create a random number smaller than 10.000
    var number = Math.floor(Math.random() * 10000);
    // Send that number to the child process:
    child.stdin.write(number + "\n");
    // Get the response from the child process and print it:
    child.stdout.once('data', function(data) {
        console.log('child replied to ' + number + ' with: ' + data);
    });
}, 1000);
child.stderr.on('data', function(data) {
    process.stdout.write(data);
});

从第一行到第四行启动了一个用来运行“+1应用”的子进程,然后使用setInterval函数每秒钟执行一次下列操作:

1..新建一个小于10000的随机数
2.将这个数字作为字符串传递给子进程
3.等待子进程回复一个字符串
4.因为你想每次只接收1个数字的计算结果,因此需要使用child.stdout.once而不是child.stdout.on。如果使用了后者,会每隔1秒注册一个data事件的回调函数,每个被注册的回调函数都会在子进程的stdout接收到数据时被执行,这样你会发现同一个计算结果会被输出多次,这种行为显然是错的。

在子进程退出时接收通知

当子进程退出时,exit事件会被触发。例8-8展示了如何监听它:

例 8-8: 监听子进程的退出事件 (chapter8/09_listen_child_exit.js)

复制代码 代码如下:


var spawn = require('child_process').spawn;
// 生成子进程来执行 "ls -la"命令
var child = spawn('ls', ['-la']);
child.stdout.on('data', function(data) {
    console.log('data from child: ' + data);
});

// 当子进程退出:
<strong>child.on('exit', function(code) {
    console.log('child process terminated with code ' + code);
});</strong>

最后几行加黑的代码,父进程使用子进程的exit事件来监听它的退出事件,当事件发生时,控制台显示相应的输出。子进程的退出码会被作为第一个参数传递给回调函数。有些程序使用一个非0的退出码来代表某种失败状态。比如,如果你尝试执行命令“ls –al click filename.txt”,但是当前目录没有这个文件,你就会得到一个值为1的退出码,见例8-9:

例8-9:获得子进程的退出码 (chapter8/10_child_exit_code.js)

复制代码 代码如下:


var spawn = require('child_process').spawn;
// 生成子进程,执行"ls does_not_exist.txt" 命令
var child = spawn('ls', ['does_not_exist.txt']);
// 当子进程退出
child.on('exit', function(code) {
    console.log('child process terminated with code ' + code);
});

这个例子里,exit事件触发了回调函数,并把子进程的退出码作为第一个参数传递给它。如果子进程是被信号杀死而导致的非正常退出,那么相应的信号代码会被当作第二个参数传递给回调函数,如例8-10:

LISTING 8-10: 获得子进程的退出信号(chapter8/11_child_exit_signal.js)

复制代码 代码如下:


var spawn = require('child_process').spawn;
// 生成子进程,运行"sleep 10"命令
var child = spawn('sleep', ['10']);
setTimeout(function() {
    child.kill();
}, 1000);
child.on('exit', function(code, signal) {
    if (code) {
        console.log('child process terminated with code ' + code);
    } else if (signal) {
        console.log('child process terminated because of signal ' + signal);
    }
});

这个例子里,启动一个子进程来执行sleep 10秒的操作,但是还没到10秒就发送了一个SIGKILL信号给子进程,这将会导致如下的输出:

复制代码 代码如下:


child process terminated because of signal SIGTERM

发送信号并杀死进程

在这部分,你将学习如何使用信号来管理子进程。信号是父进程用来跟子进程通信,甚至杀死子进程的一种简单方式。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wgspdp.html