【发布时间】:2009-10-18 03:05:11
【问题描述】:
在 POSIX 环境中有很多可能的错误。为什么其中一些(特别是写入未连接的套接字)以信号的形式得到特殊处理?
【问题讨论】:
标签: sockets error-handling signals posix
在 POSIX 环境中有很多可能的错误。为什么其中一些(特别是写入未连接的套接字)以信号的形式得到特殊处理?
【问题讨论】:
标签: sockets error-handling signals posix
这是设计使然,因此在管道中使用的生成文本的简单程序(例如 find、grep、cat)会在其消费者死亡时终止。也就是说,如果您正在运行像find | grep | sed | head 这样的链,head 将在读取足够多的行后立即退出。这将使用 SIGPIPE 杀死 sed,这将使用 SIGPIPE 杀死 grep,这将使用 SEGPIPE 杀死 find。如果没有 SIGPIPE,天真的编写的程序将继续运行并生成没人需要的内容。
如果您不想在程序中获取 SIGPIPE,只需调用 signal() 将其忽略即可。之后,像 write() 这样的系统调用遇到了损坏的管道,将返回 errno=EPIPE。
【讨论】:
请参阅此 SO 答案以详细解释为什么编写封闭描述符/套接字会生成 SIGPIPE。
【讨论】:
SIGPIPE 不是特定于套接字的——正如名称所暗示的,当您尝试写入管道(匿名或命名)时也会发送它。我想有单独的错误处理行为的原因是不应该总是将损坏的管道视为错误(而例如,尝试写入不存在的文件应该总是被视为错误)。
考虑程序less。该程序从stdin 读取输入(除非指定了文件名),并且一次只显示其中的一部分。如果用户向下滚动,它将尝试从stdin 读取更多输入并显示。由于它不会一次读取所有输入,如果用户在读取所有输入之前退出(例如通过按q),管道将被破坏。不过,这并不是一个真正的问题,所以写下管道的程序应该优雅地处理它。
【讨论】:
SIGFPE 或SIGSEGV),而不是而不是系统调用——而SIGPIPE 被发送以响应系统调用(write())。
这取决于设计。
一开始人们使用信号来控制发送到用户空间的事件通知,后来就没有必要了,因为有更流行的骨架,例如轮询,不需要系统调用者来制作信号处理程序.
【讨论】: