在Linux中,等待IO的进程可以处于TASK_INTERRUPTIBLE
或TASK_UNINTERRUPTIBLE
状态。
例如,后者是进程等待直到常规文件中的read
完成的情况。如果此read
需要很长时间或永久(无论出于何种原因),则会导致该过程在此期间无法接收任何信号的问题。
前者是这样的情况,例如,一个人等待来自套接字的read
(可能需要无限的时间)。但是,如果这样的read
调用被中断,则会导致程序员/用户正确处理errno == EINTER
条件的问题,这可能会让他忘记。
我的问题是:是否不可能允许所有系统调用被信号中断,而且,在信号处理程序运行之后,原始系统调用只是继续其业务?这不会解决这两个问题吗?如果不可能,为什么?
答案 0 :(得分:0)
问题的两半是相关的,但我可能已经消化了过多的尖刺蛋酒,以确定是否有这么多的一对一而不是一对一的关系。
在内核方面,我认为几年前就增加了TASK_KILLABLE
州。这样做的结果是,虽然进程在系统调用中被阻塞(无论出于何种原因),但如果内核遇到了无论如何都要杀死进程的信号,那么它将让大自然走上正轨。这降低了进程永久陷入不间断状态的可能性。在改变个别系统调用以利用我不知道的选项方面取得了哪些进展。
在用户方面,SA_RESTART
及其便利功能表兄siginterrupt
走了一段路,以缓解应用程序员的痛苦。但事实上,这些是按信号指定的并且不受所有系统调用的尊重,这是一个很好的暗示,有理由说明像你提出的全面中断方案无法实现,或者至少很容易实现。只考虑信号矩阵的可能交互,单个系统调用,具有历史预期和后向支持行为的调用(以及可能基于其系统血统的多个历史语义!),有点令人眼花缭乱。但也许这就是蛋酒。