【问题标题】:Why does writing to an unconnected socket send SIGPIPE first?为什么写入未连接的套接字首先发送 SIGPIPE?
【发布时间】:2009-10-18 03:05:11
【问题描述】:

在 POSIX 环境中有很多可能的错误。为什么其中一些(特别是写入未连接的套接字)以信号的形式得到特殊处理?

【问题讨论】:

    标签: sockets error-handling signals posix


    【解决方案1】:

    这是设计使然,因此在管道中使用的生成文本的简单程序(例如 find、grep、cat)会在其消费者死亡时终止。也就是说,如果您正在运行像find | grep | sed | head 这样的链,head 将在读取足够多的行后立即退出。这将使用 SIGPIPE 杀死 sed,这将使用 SIGPIPE 杀死 grep,这将使用 SEGPIPE 杀死 find。如果没有 SIGPIPE,天真的编写的程序将继续运行并生成没人需要的内容。

    如果您不想在程序中获取 SIGPIPE,只需调用 signal() 将其忽略即可。之后,像 write() 这样的系统调用遇到了损坏的管道,将返回 errno=EPIPE。

    【讨论】:

      【解决方案2】:

      请参阅此 SO 答案以详细解释为什么编写封闭描述符/套接字会生成 SIGPIPE

      Why is writing a closed TCP socket worse than reading one?

      【讨论】:

        【解决方案3】:

        SIGPIPE 不是特定于套接字的——正如名称所暗示的,当您尝试写入管道(匿名或命名)时也会发送它。我想有单独的错误处理行为的原因是不应该总是将损坏的管道视为错误(而例如,尝试写入不存在的文件应该总是被视为错误)。

        考虑程序less。该程序从stdin 读取输入(除非指定了文件名),并且一次只显示其中的一部分。如果用户向下滚动,它将尝试从stdin 读取更多输入并显示。由于它不会一次读取所有输入,如果用户在读取所有输入之前退出(例如通过按q),管道将被破坏。不过,这并不是一个真正的问题,所以写下管道的程序应该优雅地处理它。

        【讨论】:

        • Socket 只是一个例子。问题很笼统。
        • 那么,您对哪种信号感兴趣?其中许多是异步发送的(即不响应程序请求的任何特定操作),或者它们是响应硬件异常(例如SIGFPESIGSEGV),而不是而不是系统调用——而SIGPIPE 被发送以响应系统调用(write())。
        • (P.S. 为上述评论中的流浪 HTML 实体道歉。它应该是一个破折号,但 SO 似乎从字面上解释了它。)
        【解决方案4】:

        这取决于设计。

        一开始人们使用信号来控制发送到用户空间的事件通知,后来就没有必要了,因为有更流行的骨架,例如轮询,不需要系统调用者来制作信号处理程序.

        【讨论】:

        • 你能提供一些参考吗?
        • 传统信号只能处理每个 FD 通知,而且信号不是事件驱动的框架——很容易忘乎所以并尝试将信号系统变成程序的事件驱动驱动程序,但是信号处理功能不是为此而生的。所以只有一些与 FD 功能相关的 SIGXXX 和系统行为被定义。请谷歌“per FD RT signal posix select poll AIO”了解详情。
        猜你喜欢
        • 2011-08-05
        • 2013-10-30
        • 1970-01-01
        • 2011-07-16
        • 2013-03-21
        • 2017-11-24
        • 2014-06-19
        • 2021-10-29
        • 2013-11-27
        相关资源
        最近更新 更多