ChildProcess是运行还是死机? - node.js

时间:2016-04-16 18:34:27

标签: node.js child-process

在给出ChildProcess实例时,是否有任何官方(文件化)方式如何确定该过程是否仍然存在或死亡?

我不想听exit事件,我只想同步获取该过程是否已经终止的信息。

到目前为止,我发现没有记录:

const isAlive = process.exitCode === null;

1 个答案:

答案 0 :(得分:1)

假设"死了"你的意思是这个过程不再运行,"正确"方法是听ChildProcess' exit事件。

除此之外,它取决于您运行该流程的架构。

在Linux上

在支持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');
}

在OSX(或其他类Unix操作系统)

检查进程状态的唯一通用方法是转发到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进行测试。

在Windows上

可以使用相同的方法(执行命令来检查进程状态)但不是ps,而是需要使用the Windows-specific tasklist command来检索有关特定进程的信息