【问题标题】:Correctly processing Ctrl-C when using poll()使用 poll() 时正确处理 Ctrl-C
【发布时间】:2017-04-22 04:56:42
【问题描述】:

我正在制作一个程序,它像服务器一样运行,所以它一直在运行poll。我需要同时处理 Ctrl-CCtrl-D。虽然在使用 pollCtrl-D 很容易使用(你也可以在 POLLIN 上使用 poll POLLIN stdin),但我不能来为信号提供了一个漂亮的解决方案。我是否需要创建一个虚拟文件,我的信号处理程序将在退出时向其中写入一些内容,或者管道是否适合此目的?

【问题讨论】:

  • 管道 = 虚拟文件?或者您是在谈论将文件写入磁盘?从 poll() 捕获信号的正常解决方案是从信号处理程序将单个字节写入非阻塞管道。
  • 请标记正确的平台(Linux?)
  • @DietrichEpp 我的意思是创建一个pipe 并在SIGINT 出现时写信给它。
  • 信号不应该导致pollEINTR 退出,这样您就可以检查信号处理程序设置的标志了吗?

标签: c linux


【解决方案1】:

正如Dietrich Epp 所评论的,处理此问题的常用方法是“管道到自我”技巧。首先,在初始化时,您设置了一个pipe(7):您将调用pipe(2),并将该管道的读取和写入文件描述符保存在某些(例如全局)数据中。您的信号处理程序只需 write(2) 到写入端 fd 一些字节(可能是单个 0 字节......)。当读取端文件描述符有一些数据时,您围绕poll(2)(或较旧的select(2) 等...)的事件循环将响应read(2)-ing 字节。

这种管道到自我的技巧很常见,并且适用于所有 POSIX 系统,并且推荐使用,例如by Qt.

signalfd(2) 系统调用是特定于 Linux 的(例如,您在 MacOSX 上没有)。一些旧的 Linux 内核可能没有它。

请注意,信号处理程序中可用的函数集仅限于 async-signal-safe 函数 - 因此您可以使用 write(2),但禁止使用 fprintf 或 @ 987654334@ 在信号处理程序中。 仔细阅读signal(7)signal-safety(7)

【讨论】:

  • 感觉 signalfd 是一个更好的解决方案,因为它是针对这种情况的内置解决方案。
  • 从头开始,signalfd 显然是 Linux 的东西,所以对于 macOS 兼容,你仍然需要它。
【解决方案2】:

signalfd 是你所追求的 - 将它连接到 SIG_INT 并且你可以轮询 ctrl+c - 请参阅提供的链接中的示例(相当向下页面——实际上,他们正在在那里捕捉 ctrl+c...)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-09
    • 2020-01-28
    • 2012-05-04
    • 1970-01-01
    • 2022-01-14
    • 1970-01-01
    • 1970-01-01
    • 2013-08-19
    相关资源
    最近更新 更多