【问题标题】:SIGALRM to interrupt syscallSIGALRM 中断系统调用
【发布时间】:2014-08-04 21:10:27
【问题描述】:

我需要在超时后中断系统调用(在这种情况下为recvfrom)。为此,我使用alarm(),但是生成的 SIGALRM 会杀死我的进程,而不仅仅是中断系统调用。

我尝试调用signal(SIGALRM, SIG_IGN) 来处理SIGALRM,但这会导致系统调用根本不会被中断!我让它工作的唯一方法是创建一个自定义的空处理程序 (signal(SIGALRM, alrm_handler)) - 处理程序什么都不做,但它仍然会导致 recvfrom 被中断而不会杀死进程。

我知道默认信号处理程序 (SIG_DFL) 会终止进程,但我希望 SIG_IGN 忽略信号但仍会中断系统调用。我straced 一个带有 SIG_IGN 和自定义空处理程序的测试程序,他们最终都调用了 rt_sigaction(SIGALRM...) 而没有 SA_RESTART。据我所知,如果设置了 SA_RESTART ,那么系统调用将自动重新启动,但无论如何 SIG_IGN 都会发生这种情况!

有没有更简洁的方法来使用 SIGALRM 中断系统调用,而无需自定义信号处理程序?

【问题讨论】:

    标签: c linux signals


    【解决方案1】:

    当您告诉操作系统忽略一个信号时,如果当它发出信号时它什么都不做而忽略它,您不应该感到惊讶。 POSIX 仅允许 recvfrom 在被中断时返回 EINTR,并且仅在调用信号处理程序时才会中断。当SIG_IGN 设置为POSIX requires 时,“信号的传递将不会影响进程。”

    对套接字操作进行超时的更好方法是使用setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, ...) 在套接字上设置超时。如果超时,您将收到 EAGAINEWOULDBLOCK 错误。

    您可能还想查看select,它可以潜在地消除使用超时的需要。

    【讨论】:

      猜你喜欢
      • 2021-09-19
      • 2015-01-09
      • 2011-08-06
      • 1970-01-01
      • 2022-11-24
      • 1970-01-01
      • 2015-07-14
      • 2016-02-01
      • 2016-01-30
      相关资源
      最近更新 更多