是ChildProcess运行还是死? – node.js
是否有任何官方(logging)的方式,给ChildProcess
实例如何找出过程是否还活着或死亡?
我不想听exit
事件,我只想同步获取进程是否已经终止的信息。
到目前为止,我发现无证件:
const isAlive = process.exitCode === null;
假设“死”意味着进程不再运行,“正确的”方法是监听ChildProcess的exit
事件。
除此之外,它取决于您正在运行该过程的体系结构。
在Linux上
在支持procfs(进程伪文件系统)的 Linux上,您可以通过检查/proc
目录下其id
的存在来检查进程的状态。
假设你的subprocessID是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'); }
在OSX(或其他类Unix操作系统)
检查进程状态的唯一通用方法是通过shell 命令来查看单个进程或当前已知进程列表的状态。
但是,这不是(也不能)使用小于和包括v0.10.44(其依赖于事件来处理与外部进程的所有通信)的节点版本的同步过程。
对于版本大于v0.10.44的节点,可以使用标准的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
命令来检索进程的运行状态,从string中提取有用状态(使用正则expression式在该行上查找正确的行和字段) ,并根据进程报告的运行状态返回true或false。
需要注意的是,对于大于v0.10.44
的Node版本,对v0.10.44
的调用是同步的 ,因此将阻止事件循环执行其他任何操作,直到subprocess完成。
该代码已经使用Node v4.0.0进行了testing。
在Windows上
可以使用相同的方法(执行命令来检查进程状态),但是您可能需要使用Windows特定的tasklist
命令来检索有关特定进程的信息。