【问题标题】:C - recvfrom and signalC - recvfrom 和信号
【发布时间】:2012-11-18 18:31:41
【问题描述】:

我想处理 SIGUSR1 信号,所以我做它需要的一切并且它正在工作。但是在我的程序中,我在 recvfrom 等待,当我处理信号并返回到 recvfrom 时,我从这个函数中得到了 -1。是否可以返回等待此功能?

【问题讨论】:

    标签: c sockets udp signals


    【解决方案1】:

    您的系统调用是interrupted 的信号。除非您始终使用带有SA_RESTART 标志的sigaction 设置信号处理程序,否则最好使用以下循环重试系统调用:

    while ((size = recvfrom(...)) == -1 && errno == EINTR)
      ;
    

    【讨论】:

      【解决方案2】:

      它应该返回-1并将errno设置为EINTR然后你应该尝试再次调用它,或者在设置信号处理程序时使用SA_RESTART标志,这应该允许recvfrom重新启动它被信号中断了。

      来自 man signal(7) 页面:

      如果对以下接口之一的阻塞调用被中断 通过信号处理程序,然后调用将自动重新启动 如果使用了 SA_RESTART 标志,则在信号处理程序返回之后;否则调用将失败并返回错误 EINTR:

      套接字接口:accept(2), connect(2)、recv(2)、recvfrom(2)、recvmsg(2)、send(2)、sendto(2) 和 sendmsg(2),除非在套接字上设置了超时(见下文)

      【讨论】:

      • 感谢您的两个回答。我选择第二个,因为当我设置 SA_RESTART 标志时,它会等到 recvfrom 获取数据然后在处理程序中执行命令,然后继续执行其余代码,并且我需要在获取信号后立即在处理程序中执行代码。不过也谢谢你。
      • @Bibo 没关系,但 AFAIK 不应该,你如何设置标志?我想你正在使用sigaction 对吧?
      • ´sa.sa_flags = SA_RESTART´ 不知道是否不同,但我使用的是 FreeBSD。
      • @Bibo 你在套接字上设置超时吗?与setsockopt ?如果不是,是的,在 BSD 上可能会有所不同,请查看系统上的手册页。
      • 不,不设置超时。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多