为什么写入未连接的套接字首先发送SIGPIPE?

时间:2009-10-18 03:05:11

标签: sockets error-handling signals posix

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

4 个答案:

答案 0 :(得分:4)

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

如果您不想在程序中使用SIGPIPE,只需通过调用signal()来忽略它。之后,遇到破坏管道的类似write()的系统调用将返回errno = EPIPE。

答案 1 :(得分:1)

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

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

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

取决于设计。

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