我正在阅读优秀的在线书籍http://nodebeginner.org/并尝试使用简单的代码
var http = require("http");
function onRequest(request, response) {
response.writeHead(200, {"Content-Type": "text/plain"});
response.write("Hello World");
response.end();
}
http.createServer(onRequest).listen(8888);
Run Code Online (Sandbox Code Playgroud)
现在我不知道(我仍然不知道!)如何优雅地关闭node.js,所以我就去了ctrl+z.现在,每次我尝试运行时node server.js,都会收到以下错误消息.
node.js:134
throw e; // process.nextTick error, or 'error' event on first tick
^
Error: EADDRINUSE, Address already in use
at Server._doListen (net.js:1100:5)
at net.js:1071:14
at Object.lookup (dns.js:153:45)
at Server.listen (net.js:1065:20)
at Object.<anonymous> (/Users/Bob/server.js:7:4)
at Module._compile (module.js:402:26)
at Object..js (module.js:408:10)
at Module.load (module.js:334:31)
at Function._load (module.js:293:12)
at Array.<anonymous> (module.js:421:10)
Run Code Online (Sandbox Code Playgroud)
那么,有两个问题:
1)如何正常关闭node.js?
2)如何修复我创造的混乱?
我有一个程序可以创建许多线程并运行,直到电源关闭到嵌入式计算机,或者用户使用kill或ctrlc终止进程.
这是一些代码以及main()的外观.
static int terminate = 0; // does this need to be volatile?
static void sighandler(int signum) { terminate = 1; }
int main() {
signal(SIGINT, sighandler);
// ...
// create objects, spawn threads + allocate dynamic memory
// ...
while (!terminate) sleep(2);
// ...
// clean up memory, close threads, etc.
// ...
signal(SIGINT, SIG_DFL); // is this necessary?
}
Run Code Online (Sandbox Code Playgroud)
我想知道一些事情:
是否需要任何信号处理?
我在这个帖子中读到了"Linux C catch kill信号以便正常终止",显然操作系统会为我处理清理工作.因此,我可以只用无限循环替换信号处理程序,让操作系统优雅地退出线程,取消分配内存等吗?
关于清洁终止,我还需要关注其他任何信号吗?这个主题"SIGINT如何与其他终止信号相关?" ,列出我可能关注的所有信号,但有多少实际需要处理是有用的?
我的示例中的terminate变量是否必须是volatile?我已经看到很多这个变量是易变的例子,而其他的变量则不是.
我已经读过, …
当涉及到进程树时,SIGTERM和SIGKILL有什么区别?
当一个根线程接收到SIGKILL时,它会被彻底杀死,还是会让它的子线程变成僵尸?
是否有任何信号可以通过不离开任何僵尸线程发送到根线程干净地退出?
谢谢.
我想知道为什么这两个信号在一个进程中不能被捕获、阻止或忽略?可以使用 signal() 更改其余信号的操作。这两个信号和其余信号有什么区别?
我发现了一篇关于相关主题的不同帖子(如何在退出时执行异步操作),但它可能不适用于 macOS,或者在运行 Node.js v14 时不再适用。
我原来的问题更复杂。我无法在 SIGINT 的回调(或异步回调)中正常工作setTimeout。await但后来我意识到我真正需要做的,首先也是最重要的是能够捕获并忽略SIGINT。
如果我能做到这一点,那么如果我愿意的话,我也可以关闭以响应 SIGINT。
所以我回到基础知识,看看是否可以简单地禁用 SIGINT。我不能。
我可以检测到 SIGINT,我可以用控制台消息或任何其他同步代码进行响应,但无论我做什么,我的代码都会关闭,而且很快就会关闭。
process.on('SIGINT', () => { console.log('here'); return false; });
process.on('SIGINT', () => { console.log('here'); return true; });
process.on('SIGINT', () => { console.log('here'); return undefined; });
process.on('SIGINT', () => { console.log('here'); return new Promise(resolve => { console.log(resolve); }); });
Run Code Online (Sandbox Code Playgroud)
Ctrl这些方法都无法阻止我的 Node.js 服务器在点击+后关闭C,或者以其他方式向进程发送 SIGINT。
更新:
当我通过运行我的服务器时node app.js,SIGINT 拦截正在正常工作!
显然,我已经被通过nodemon. 来自我的 IDE 终端的+或使用 …
在终端中,我启动后台进程A,后者又启动进程B.进程B写入终端(进程A已经向B传递了正确的TTY文件描述符).
我担心的是,如果用户(在某些情况下,我)关闭终端窗口而不发送进程A或B一个SIGINT.然后可能发生的是,即使用户关闭了进程B,进程B仍将尝试写入终端.更糟糕的是,用户可以打开一个新的终端窗口,它可能会采用与另一个终端相同的身份/文件描述符,然后由进程B写入.
基本上,我正在寻找一种"监听"终端会话事件的方法,例如终端会话被关闭.
是否可以在Node.js进程中侦听此类事件?也许有一个相应的处理程序类似process.on('SIGINT')?
我猜测也许SIGTERM事件是要听的事件,但现在在试验代码后,不要以为是这样.