ChildProcess 运行 是死了吗? - node.js

Is ChildProcess running or dead? - node.js

是否有任何正式的(记录的)方法,给定 ChildProcess 实例如何找出进程是仍然活着还是死了?

不想监听exit事件,只想同步获取进程是否已经终止的信息

到目前为止我发现未记录:

const isAlive = process.exitCode === null;

假设 "dead" 你的意思是进程不再是 运行ning,"correct" 方法是监听 ChildProcess 的 exit 事件。

除此之外,这取决于您运行执行该过程的架构。

在 Linux

在支持 procfs - the process pseudo-filesystem 的 Linux 上,您可以通过检查 /proc 目录下是否存在其 id 来检查进程的状态。

假设您的子进程 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 操作系统)上

检查进程状态的唯一通用方法是 shell 到 ps command 查看单个进程或当前已知进程列表的状态。

但是,这不是(也无法做到)使用小于并包括 v0.10.44 的 Node 版本的同步进程(它依赖于事件来处理与外部进程的所有通信)。

对于高于 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..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 命令检索 运行 进程状态,从字符串中提取有用的状态(使用正则表达式找到正确的行和该行上的字段),以及 returns true 或 false,具体取决于报告的进程 运行状态。

非常重要要注意,对于大于 v0.10.44 的 Node 版本,调用 child_process.spawnSync 同步的 因此,将 阻止事件循环 在子进程完成之前不做任何其他事情。

此代码已使用 Node v4.0.0 进行测试。

在 Windows

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