【问题标题】:fs.read prevents process.exit in custom signal handlerfs.read 在自定义信号处理程序中阻止 process.exit
【发布时间】:2016-04-05 14:33:37
【问题描述】:

我无法在信号处理程序中使用process.exit() 让我的nodejs 应用程序退出。这是因为我在 Linux 输入事件节点 (/dev/input/mouse1) 上有一个挂起的读取操作。我花了几个小时研究,但我只能找到this SO question。我尝试使用fs.ReadStream 就像在那里使用的那样并调用它的destroy 方法,但它也没有工作。即使通过阅读 nodejs 源代码,我也无法想出一个主意。然后是这个issue on github,有点相关。

到目前为止,我想出了一些技巧来解决这个问题,但没有什么干净的:

  1. 使用比process.exit更强的东西,也许process.abort
  2. 生成一个子进程 (childProcess.fork) 到 read,我可以从父进程终止它。但这会创建一个新的 nodejs 实例,内存使用量约为 10mb。
  3. 用我可以更好地控制正在发生的事情(使用线程等)的语言 (C++) 编写程序并从 javascript 调用它。虽然我更喜欢留在 js-land。
  4. 或者也许有人知道可以帮助我以不同方式实现目标的工具? (请参阅下面的背景信息)。也许我不必使用/dev/input/

基本上,我需要一种直接或间接取消挂起的read 操作的方法(例如,通过从active_handles 列表中清除它们)。
提前感谢您的回答!

示例

在下面的代码示例中,我可以按ctrl+c,但nodejs只有在我移动鼠标后才会退出:

'use strict'
const fs = require('fs');

const buf = new Buffer(24);
const mouse = fs.openSync('/dev/input/mouse1', 'r');
const onRead = (err, bytesRead, buffer) => {
    console.log('read');
    if (!err) {
        process.nextTick(fs.read, mouse, buf, 0, buf.length, null, onRead);
    }
};
fs.read(mouse, buf, 0, buf.length, null, onRead);

process.on('SIGINT', () => {
    fs.closeSync(mouse);
    process.exit();
});

背景资料

我正在开发一个基于运行 nodejs 脚本的树莓派的小项目。我希望程序通过 USB 鼠标的滚轮和 GPIO 附加按钮来响应用户输入。因此,我将onoff 库用于GPIO 的东西。 onoff 文档建议安装自定义 SIGINT 处理程序以在程序退出之前释放资源,这就是这种愿望的来源。为了在没有窗口系统甚至终端的情况下处理滚轮数据,我最终想让this library工作,但现在我遇到了上述问题。

【问题讨论】:

  • 您是否检查过信号处理程序是否被实际调用?您使用fs.openSyncfs.read 而不是fs.createReadStream 并添加read 事件处理程序的任何具体原因? pstop中的进程在尝试中断时处于什么状态?
  • @jcaron 感谢您的回复。这段代码只是一个简单的例子。我在问题中提到我已经使用 ReadStream 测试了替代实现。此外,fs.ReadStream 只是 fs.read 的某种包装,请参阅here。处理程序被调用,您甚至可以从中console.log。能否详细说明如何在top/ps中查找进程状态?
  • 我今天也偶然发现了这个。一种解决方案是使用诸如 node-hid 之类的库,它使用 hidapi,并在内部进行了足够的清理,但我想避免添加另一个需要编译的库。感谢您提供解决方法列表。最后,您是否设法为此找到了另一种解决方案?
  • @AndreT 这是 5 年前的事了:D 但 IIRC 这是一门我最终完全放弃的单门课程。所以恐怕没有解决办法。我遵循的最后一种方法是将我自己的事件输入设备,以便 nodejs 的 io lib 中的阻塞线程将恢复并允许我正确关闭。不确定我是否可以正常工作...

标签: linux node.js


【解决方案1】:

可能有点粗略,但以下内容呢:

process.on('SIGINT', () => {
    fs.closeSync(mouse);
    setTimeout(process.exit, 1000);
});

【讨论】:

  • 您好,感谢您的回答。它能为您提供帮助吗?我在发布这个问题之前尝试过,但它对我不起作用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-30
  • 1970-01-01
  • 2013-11-29
  • 1970-01-01
  • 2022-06-14
  • 1970-01-01
相关资源
最近更新 更多