【问题标题】:Why can a signal handler not run during system calls?为什么信号处理程序不能在系统调用期间运行?
【发布时间】:2023-04-01 23:33:01
【问题描述】:

在 Linux 中,等待 IO 的进程可以处于 TASK_INTERRUPTIBLETASK_UNINTERRUPTIBLE 的任一状态。

例如,后者是进程等待直到来自常规文件的read 完成的情况。如果这个read 需要很长时间或永远(无论出于何种原因),则会导致进程在此期间无法接收任何信号的问题。

前一种情况是,例如,一个人等待来自套接字的read(这可能需要无限的时间)。但是,如果这样的read 调用被中断,则会导致需要程序员/用户正确处理errno == EINTER 条件的问题,他可能会忘记这一点。

我的问题是:难道不能让所有系统调用都被信号中断,而且,在信号处理程序运行后,原始系统调用会继续其业务吗?这不是解决了这两个问题吗?如果不可能,为什么?

【问题讨论】:

  • 简短的回答是否定的。长答案将涉及比我熟悉的更深入的 CPU 和操作系统内部。

标签: linux signals


【解决方案1】:

问题的两半是相关的,但我可能消化了太多的加糖蛋酒,无法确定这里是否存在如此多的一对一关系而不是一对多关系。

在内核方面,我认为TASK_KILLABLE 状态是几年前添加的。这样做的结果是,当进程在系统调用中阻塞时(无论出于何种原因),如果内核遇到一个无论如何都会杀死进程的信号,它就会顺其自然。这减少了进程永久卡在不间断状态的机会。我不知道在更改单个系统调用以利用该选项方面取得了哪些进展。

在用户方面,SA_RESTART 和它的便利功能表亲siginterrupt 在减轻应用程序程序员的痛苦方面有一定的距离。但是,这些是每个信号指定的,并且并非所有系统调用都遵守这一事实,这是一个很好的暗示,说明为什么像您建议的全面中断方案无法实现或至少无法轻松实现是有原因的。仅仅考虑信号矩阵、单个系统调用、具有历史预期和向后支持行为的调用(以及可能基于其系统血统的多个历史语义!)之间可能的交互,有点令人眼花缭乱。但也许这就是蛋酒。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多