有没有办法制作仅限进程内部的有条件中断信号?
我正在寻找一种方法,从信号处理程序内部,有条件地中断在处理信号时发生的系统调用。为了具体说明这一点,假设正在调用 read
,并且收到 SIGRT0
。此信号处理程序使用 SA_RESTART
因为它不想无条件中断系统调用,但根据条件,我希望导致 read
返回 EINTR
信号处理程序返回后立即执行。
我可以做到这一点的一种方法是为 SIGRT1
设置另一个信号处理程序,将 SIGRT1
放入 SIGRT0
处理程序的信号掩码中,然后从 SIGRT1
处理程序中省略 SA_RESTART
。然后,SIGRT0
的处理程序可以raise
SIGRT1
,当第一个非中断信号处理程序返回时,第二个信号处理程序将触发并>read
被中断。
此解决方案的问题在于其他进程可能会发送 SIGRT1
,从而导致出现不需要的 EINTR
情况。
有什么办法可以达到我想要的结果吗?
I'm looking for a way to, from within a signal handler, conditionally interrupt a syscall that way taking place at the time the signal was handled. To make this concrete, suppose a call to read
is in process, and SIGRT0
is received. This signal handler uses SA_RESTART
because it does not want to unconditionally interrupt syscalls, but depending on a condition, I want to cause read
to return EINTR
immediately once the signal handler returns.
One way I could do this is by setting up another signal handler for SIGRT1
, putting SIGRT1
in the signal mask for SIGRT0
's handler, and omitting SA_RESTART
from the SIGRT1
handler. Then the handler for SIGRT0
can raise
SIGRT1
, and when the first, non-interrupting signal handler returns, the second one will fire and read
gets interrupted.
The problem with this solution is that other processes could send SIGRT1
, causing unwanted EINTR
occurrences.
Is there any way to achieve the result I'm looking for?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果您想设置一个特定的进程来发送该信号,那么您可以使用任何 IPC 技术(例如管道)来共享其 pid id 和标志,以确保该信号是由该进程发送的。如果进程没有发送信号,则忽略它。
If you want to set a particular process to send that signal then you can any IPC techniques (e.g. pipe) to share its pid id and flags to make sure that signal was sent by that process. If signal wasn't sent by the process then just ignore it.
由于多种原因,我想要的东西是不可能的。也许最重要的是,一旦第一个信号处理程序返回,但在中断的系统调用重新启动之前,用于中断的辅助信号可能会(实际上在大多数系统上)触发。然后系统调用将重新启动并继续阻塞。
也许更重要的是,任何故意使用 EINTR 中断阻塞系统调用的尝试都会受到竞争条件的影响,其中信号恰好在阻塞系统调用之前到达,但在任何检查之后都会由于收到了信号。唯一可以接受的时间是当您准备发出多个信号并增加它们之间的延迟直到“中断请求”得到满足时,但这已经进入了片状黑客的领域......
What I wanted was impossible for multiple reasons. Perhaps most importantly, the secondary signal that was intended to do the interrupting would potentially (and in reality on most systems) fire as soon as the first signal handler returned but before the interrupted syscall got restarted. Then the syscall would restart and continue to block.
Perhaps more importantly, any attempt to interrupt blocking syscalls with
EINTR
intentionally is subject to race conditions where the signal arrives just before the blocking syscall, but after whatever check would have prevented making the syscall due to having received the signal. The only time this might be acceptable is when you're prepared to fire off multiple signals with increasing delays between them until the "interupt request" is honored, but that's getting into the realm of flaky hacks...