在给出ChildProcess
实例时,是否有任何官方(文件化)方式如何确定该过程是否仍然存在或死亡?
我不想听exit
事件,我只想同步获取该过程是否已经终止的信息。
到目前为止,我发现没有记录:
const isAlive = process.exitCode === null;
答案 0 :(得分:1)
假设"死了"你的意思是这个过程不再运行,"正确"方法是听ChildProcess' exit
事件。
除此之外,它取决于您运行该流程的架构。
在支持procfs - the process pseudo-filesystem的Linux上,您可以通过检查id
目录下/proc
的存在来检查进程的状态。
假设您的子进程ID为1234,阅读/proc/1234/status
,您会发现有关该流程的大量信息,包括:
State: R (running)
var fs=require('fs'),
pid = 1234
procInfo;
// possible values for State value in /proc/pid/status
// R running,
// S is sleeping,
// D is sleeping in an uninterruptible wait,
// Z is zombie (not running but held by process owner)
// T is traced or stopped
try {
procInfo=fs.readFileSync('/proc/'+pid+'/status').toString();
}
catch(e){
console.error('process does not exist');
}
if(!procInfo.match(/State:\s+[RSDT]/)){
console.error('process is not running');
}
检查进程状态的唯一通用方法是转发到ps
command以查看单个进程或当前已知进程列表的状态。
但是,这不是(也不可能)使用节点版本的同步过程,该版本小于和包括v0.10.44(它依赖于事件来处理与外部进程的所有通信)。
对于大于v0.10.44的Node版本,可以使用标准child_process
函数的同步版本。
'use strict';
var util=require('util'),
nodeVersion=parseFloat(process.version.replace(/^v|\.\d+$/g,'')), // version as Major.MinorPatch like: 0.1044 for v0.10.44
pid=1234,
txt='';
// expected output from ps:
// PID TT STAT TIME COMMAND
// 1224 s000 S 0:00.08 child_process
// meaning of first letter in STAT column
// I IDLE
// R RUNNING
// S SLEEPING
// T STOPPED
// U WAIT
// Z DEAD
/**
* Returns true if process id is currently running.
*
* @param {Number|String} pid - id of process
* @param {String} str - output from `ps` command
* @return {boolean}
*/
var isProcessRunning=function(pid,str){
if(!str.match(new RegExp('(^'+pid.toString()+'.+?$)','m'))){
//throw new Error('process does not exist');
return false;
}
var parts=RegExp.$1.split(/\s+/);
if(parts.length < 5){
throw new Error('unexpected result from ps');
}
if(!parts[2].match(/^[IRSTU]/)){
//throw new Error('process is not running: %s',parts[2]);
return false;
}
return true;
};
if(nodeVersion > 0.1044){ // node versions greater than v0.10.44
var result=require('child_process').spawnSync('ps',[pid]);
console.log(util.format('process %s %s running', pid, isProcessRunning(pid,result.stdout.toString()) ? 'is' : 'IS NOT'));
}
else { // node versions less than or equal to v0.10.44
var spawn = require('child_process').spawn,
ps = spawn('ps', [pid]);
ps.stdout.on('data', function(data){
txt+=data.toString();
});
ps.stderr.on('data',function(data){
console.error('ps error: '+data);
});
ps.on('close', function() {
console.log(util.format('process %s %s running', pid, isProcessRunning(pid,txt) ? 'is' : 'IS NOT'));
});
}
isProcessRunning
函数需要pid
来检查str
这是运行ps
命令的输出,以检索进程的运行状态,提取有用的从字符串状态(使用正则表达式在该行上找到正确的行和字段),并返回true或false,具体取决于进程&#39;报道了运行状态。
非常重要 要注意,对于大于v0.10.44
的Node版本,对child_process.spawnSync
的调用是同步等等,阻止事件循环执行其他操作,直到子进程完成。
此代码使用Node v4.0.0进行测试。
可以使用相同的方法(执行命令来检查进程状态)但不是ps
,而是需要使用the Windows-specific tasklist
command来检索有关特定进程的信息