[英]Pipes in C, buffer for reading stdin
我试图理解这个答案。 特别是,数据如何跨流程流动?
I assume that input stream flows through a child's input through output connected with pipe, then is collected by a parent through pipe output. 但是,在新一轮循环并在子进程中执行命令之前,读取的数据会发生什么情况?
数据是否在父进程中缓冲(不知何故?我想知道是什么原因造成的),稍后这个缓冲区被复制并在fork()
之后传递给子进程,然后子进程将保存的输入传递给exec()
?
有一个与 pipe 关联的缓冲区。
如果缓冲区未满,则写入将返回,程序将继续。
但是缓冲区有可能被填满。 如果写入无法完成,它将导致部分写入(使用提供的写入量)或阻塞直到写入可以完成(即当某物最终从另一端读取时)。
试图从空 pipe 读取的读者通常会阻塞,直到数据可用。 如果描述符被设为非阻塞,则读取将返回错误 EWOULDBLOCK 或 EAGAIN。
select
和类似机制可用于检测何时可以安全地执行读取或写入而不会阻塞。
pipe 的每一端都可以独立闭合。 仅在关闭文件描述符的所有副本后才关闭结尾。 这包括继承的副本。 一个常见的场景是子代从其父代继承 pipe。 父级将关闭其描述符之一,而子级将关闭另一个。 这使得一个进程能够写入 pipe,而另一个进程能够从中读取。 (双向通信需要两个管道或一个套接字。)
如果读者退出会发生什么? 默认情况下,写入已关闭的 pipe 会产生 SIGPIPE 信号。 默认情况下,这会终止写入过程。 这通常非常有用。 例如,考虑在很长的 stream 上使用head
的情况。 但它并不总是有用的。 有时,您想检测并处理这种情况。 幸运的是,通过使用通常的机制处理或忽略信号,这是完全可配置的。 如果忽略,写入操作将失败并出现错误代码 EPIPE。
系统之间的行为会有差异。 例如,Windows 没有信号*, select
不适用于管道。 (不过,它确实适用于 sockets。)但它也提供了执行异步 I/O 的替代方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.