我正在寻找一种方法,从信号处理程序中有条件地中断在处理信号时发生的系统调用。为了具体说明,假设正在调用read
,并收到SIGRT0
。此信号处理程序使用SA_RESTART
,因为它不希望无条件地中断系统调用,但是根据条件,我希望在信号处理程序返回后立即使read
返回EINTR
。
我可以这样做的一种方法是为SIGRT1
设置另一个信号处理程序,将SIGRT1
放入SIGRT0
处理程序的信号掩码中,并省略SA_RESTART
来自SIGRT1
处理程序。然后SIGRT0
的处理程序可以raise
SIGRT1
,当第一个非中断信号处理程序返回时,第二个将触发,read
被中断。
此解决方案的问题在于其他进程可能会发送SIGRT1
,从而导致不必要的EINTR
次出现。
有没有办法达到我想要的结果?
答案 0 :(得分:0)
如果要设置发送该信号的特定进程,则可以使用任何IPC技术(例如管道)共享其pid id和标志,以确保该进程发送信号。如果进程未发送信号,则忽略它。
答案 1 :(得分:0)
出于多种原因,我想要的是不可能的。也许最重要的是,一旦第一个信号处理程序返回但是在中断的系统调用重新启动之前,用于中断的辅助信号可能(实际上在大多数系统上)都会激活。然后系统调用将重新启动并继续阻止。
也许更重要的是,任何试图用EINTR
故意中断阻塞系统调用的尝试都会受到阻塞系统调用之前信号到达的竞争条件的影响,但是经过任何检查都会阻止因接收到系统调用而导致系统调用信号。唯一可以接受的是当你准备发射多个信号时,它们之间的延迟会越来越大,直到“中断请求”得到尊重,但这已经进入了片状黑客的领域......