Node.js-进程在退出时挂起(Ctrl + C) [英] Nodejs - process hangs on exit (Ctrl+C)

查看:158
本文介绍了Node.js-进程在退出时挂起(Ctrl + C)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个node.js项目,它可以完成很多事情,它产生子进程,打开一个http和socket.io服务器,等等。

I have a node.js project which does many things, it spawns child processes, it opens an http and socket.io server, etc..

当我从控制台运行它,并用 Ctrl + C 关闭它,它只是挂起。
在webstorm中,停止该过程是一个两步过程,首先我单击了stop,然后我需要再次单击该按钮,仅第二次该按钮是一个头骨图标。

When I run it from the console, closing it with Ctrl+C, it just hangs. From webstorm, stopping the process is a two-step process, first I hit stop, then I need to hit the button again, only the second time the button is a skull icon.

现在,我知道它会留下一些悬而未决的东西,但我不知道是什么,我试图跟踪启动过程的所有位置,并确保已正确杀死它们。

Now, I understand it leaves something open or hanging, but I just can't figure out what, I tried to track all the places where I start a process and made sure I'm killing them properly.

有没有办法调试它并找出导致进程挂起的原因?难道是日志记录打开了一个写流,却永不关闭?我什至不知道什么样的事情会使进程挂在SIGINT上。

Is there a way to debug this and find out what's making my process hang? Could it be logging that open a write stream and never closes? I'm not even sure what kind of things will make a process hang on SIGINT.

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

I've downloaded pstree to see if any of the child processes that the main process spawns stay alive. It looks like they all terminate properly - the main node process is the only one left.

推荐答案

脚本本身负责正确关闭一旦他们听到 SIGINT 事件,就会关闭,因为默认处理程序(杀死进程)被禁用了。

Scripts are themselves responsible for properly shutting down once they listen to the SIGINT event, as the default handler (killing the process) is disabled then.

看看这个示例程序:

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()

Execute it and then try killing it: It won't work. The SIGINT signal will always get passed to your custom build signal handler. In order to properly shut the process down you will have to manually call 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. 设置一些内部标志

  2. 调用 process.on('exit') 处理程序

  3. 调用 process.reallyExit

  4. 哪个将调用 C ++ exit() 函数,因此 process.exit() final ,并且会导致关机(除非您通过您的 on('exit')处理程序。)

  1. Set some internal flags
  2. Call the process.on('exit') handlers
  3. Call process.reallyExit
  4. Which will call the C++ exit() function, therefore process.exit() is final and will cause a shutdown (unless you block execution by an endless loop in your on('exit') handler).






长话短说:您的代码可能在某处收听 SIGINT 。您可以通过以下方式获取这些侦听器的列表:


Long story short: Your code probably listens to SIGINT somewhere. You can fetch a list of those listeners via:

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

您甚至可以在控制台上漂亮地打印它们:

You can even pretty print them on the console:

for (var i = 0; i < listeners.length; i++) {
    console.log(listeners[i].toString());
}

使用我在上面提供的信息,您可以轻松地编译另一个 SIGINT -handler将列出所有处理程序,然后干净地退出该进程,希望将您的路径引向顽皮的那些程序:

Using the information I gave above you can easily compile yet another SIGINT-handler that will list all the handlers and then cleanly exit the process, hopefully leading your path to the naughty ones:

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();
});






完整的测试程序:


Complete program for testing:

process.on('SIGINT', function() {
    console.log('Naughty SIGINT-handler');
});
process.on('exit', function () {
    console.log('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.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();
});

这篇关于Node.js-进程在退出时挂起(Ctrl + C)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆