POSIX 环境中有很多可能的错误。为什么其中一些(特别是写入未连接的套接字)以信号的形式得到特殊处理?
4 回答
这是设计使然,因此在管道中使用的生成文本的简单程序(例如 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
。不过,这并不是一个真正的问题,所以写下管道的程序应该优雅地处理它。
这取决于设计。
起初人们使用信号来控制发送到用户空间的事件通知,后来就没有必要了,因为有更流行的骨架,例如轮询,不需要系统调用者来制作信号处理程序。