Nodejs - 进程在退出时挂起(Ctrl + C)

时间:2014-02-18 20:03:14

标签: node.js child-process

我有一个node.js项目,它执行很多操作,它会生成子进程,它会打开一个http和socket.io服务器等。

当我从控制台运行它时,用Ctrl+C关闭它,它就会挂起。 从webstorm开始,停止这个过程分为两个步骤,首先我点击停止,然后我需要再次点击按钮,只有第二次按钮是头骨图标。

现在,我明白它留下了一些开放或悬挂的东西,但我无法弄清楚是什么,我试图跟踪我开始一个过程的所有地方,并确保我正确地杀死它们。

有没有办法调试这个并找出使我的进程挂起的原因?可能是打开写入流并永远不会关闭的日志记录吗?我甚至不确定什么样的事情会使SIGINT上的进程挂起。

编辑:我已经下载pstree以查看主进程产生的任何子进程是否保持活动状态。看起来它们都正常终止 - 主节点进程是唯一剩下的。

1 个答案:

答案 0 :(得分:36)

脚本本身负责在收听SIGINT事件后正确关闭,因为默认处理程序(终止进程)已被禁用。

查看此示例程序:

process.on('SIGINT', function() {
    console.log('SIGINT');
});
console.log('PID: ', process.pid);

var http = require('http'); // HTTP server to keep the script up long enough
http.createServer(function (req, res) {
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end('Hello World\n');
}).listen(1337, '127.0.0.1');
console.log('Server running at http://127.0.0.1:1337/');

执行它然后尝试杀死它:它不起作用SIGINT信号将始终传递给您的自定义构建信号处理程序。为了正确关闭流程,您必须手动调用process.exit()

process.on('SIGINT', function() {
    console.log('SIGINT');
    process.exit();
});
console.log('PID: ', process.pid);

var http = require('http');
http.createServer(function (req, res) {
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end('Hello World\n');
}).listen(1337, '127.0.0.1');
console.log('Server running at http://127.0.0.1:1337/');

process.exit()将:

  1. Set some internal flags
  2. Call process.on('exit')处理程序
  3. 致电process.reallyExit
  4. 哪个will call C ++ exit()函数,因此process.exit() final 并且会导致关闭(除非您通过{无限循环阻止执行{ {1}}处理程序)。

  5. 长话短说:您的代码可能会在某处侦听on('exit')。您可以通过以下方式获取这些侦听器的列表:

    SIGINT

    你甚至可以在控制台上打印它们:

    var listeners = process.listeners('SIGINT');
    

    使用上面提供的信息,您可以轻松编译另一个for (var i = 0; i < listeners.length; i++) { console.log(listeners[i].toString()); } - 处理程序,它将列出所有处理程序,然后干净地退出该进程,希望将您的路径引导到顽皮的

    SIGINT

    完整的测试程序:

    process.on('SIGINT', function() {
        console.log('Nice SIGINT-handler');
        var listeners = process.listeners('SIGINT');
        for (var i = 0; i < listeners.length; i++) {
            console.log(listeners[i].toString());
        }
    
        process.exit();
    });