我有一个node.js项目,它执行很多操作,它会生成子进程,它会打开一个http和socket.io服务器等。
当我从控制台运行它时,用Ctrl+C
关闭它,它就会挂起。
从webstorm开始,停止这个过程分为两个步骤,首先我点击停止,然后我需要再次点击按钮,只有第二次按钮是头骨图标。
现在,我明白它留下了一些开放或悬挂的东西,但我无法弄清楚是什么,我试图跟踪我开始一个过程的所有地方,并确保我正确地杀死它们。
有没有办法调试这个并找出使我的进程挂起的原因?可能是打开写入流并永远不会关闭的日志记录吗?我甚至不确定什么样的事情会使SIGINT上的进程挂起。
编辑:我已经下载pstree
以查看主进程产生的任何子进程是否保持活动状态。看起来它们都正常终止 - 主节点进程是唯一剩下的。
答案 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()
将:
process.on('exit')
处理程序process.reallyExit
exit()
函数,因此process.exit()
final 并且会导致关闭(除非您通过{无限循环阻止执行{ {1}}处理程序)。长话短说:您的代码可能会在某处侦听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();
});