繁体   English   中英

C 中的管道,用于读取标准输入的缓冲区

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM