NodeJS子进程在SIGINT

时间:2016-11-24 11:53:11

标签: node.js linux process terminate

我正在创建NodeJS应用程序,它创建了很多子进程。它们由spawnexec启动(基于lib实现)。一些示例可能是用于图像处理的GraphicsMagick(gm)或用于OCR的Tesseract(node-tesseract)。现在我想优雅地结束我的应用程序,所以我创建了shutdown hook:

function exitHandler() {
    killer.waitForShutdown().then(function(){
        logger.logInfo("Exited successfully.");
        process.exit();
    }).catch(function(err) {
        logger.logError(err, "Error during server shutdown.");
        process.exit();
    });
}

process.on('exit', exitHandler);
process.on('SIGINT', exitHandler);
process.on('SIGTERM', exitHandler);

退出处理本身工作正常,等待很好等等,但有一个问题。当时运行的所有“原生”(gm,tesseract,...)进程也被杀死。异常消息仅包含“命令失败”,然后是失败的命令内容,例如

"Command failed: /bin/sh -c tesseract tempfiles/W1KwFSdz7MKdJQQnUifQFKdfTRDvBF4VkdJgEvxZGITng7JZWcyPYw6imrw8JFVv/ocr_0.png /tmp/node-tesseract-49073e55-0ef6-482d-8e73-1d70161ce91a -l eng -psm 3\nTesseract Open Source OCR Engine v3.03 with Leptonica"

至少对我而言,他们并没有说出任何有用的信息。我也在排队流程执行,因此PC不会一次超过50个进程。当SIGINT终止正在运行的进程时,排队的新进程将正常启动并成功完成。我只有少数在接收SIGINT时运行的问题。在Linux(Debian 8)和Windows(W10)上,这种行为是相同的。从我在这里读到的,人们通常有相反的问题(杀死子进程)。我试图搜索stdin是否以某种方式管道进入子进程,但我找不到它。它应该如何工作呢?有什么技巧可以阻止这种行为吗?

1 个答案:

答案 0 :(得分:0)

发生这种情况的原因是,默认情况下,detached选项设置为false。如果detachedfalse,则无论您是否设置了事件监听器,信号也会发送到子进程。

要阻止这种情况发生,您需要更改spawn次调用以使用第三个参数来指定detached;例如:

spawn('ls', ['-l'], { detached: true })

来自Node documentation

  

在Windows上,将options.detached设置为true可以实现   子进程在父进程退出后继续运行。孩子   将有自己的控制台窗口。一旦启用了子进程,就可以了   无法禁用。

     

在非Windows平台上,如果options.detached设置为true,则为   子进程将成为新进程组的领导者   会话。请注意,子进程可能会继续运行   父母退出,无论他们是否脱离。看到   setsid(2)了解更多信息。