有关pipe道的基本问题

对于我不确定的pipe道,我有一些基本的问题。

a)如果写入pipe道的进程被杀死,标准的行为是什么(例如SIGKILL SIGINT)是否closurespipe道? 它冲洗pipe道? 或者是行为未定义?

b)过程正常返回时的标准行为是什么? 是否保证冲洗pipe道并closurespipe道? (当然没有明确这样做)。

我希望这些答案尽可能一般,但实际上如果完全取决于操作系统的规格,我可以接受! 但是,如果有一个Posix标准或当前定义的Windows行为,我将非常感激知道。

谢谢。

一个。 什么是标准的行为,如果写入管道的进程被杀死(即。SIGKILL SIGINT)是否关闭管道? 它冲洗管道? 或者是行为未定义?

SIGKILL从不允许任何清理 – 这个过程死亡,死亡。 使用SIGINT,取决于进程是否处理信号。 如果是这样,它可能会通过退出(2),这将刷新标准的I / O文件句柄退出。 问题是 – 管道连接到标准输出或通过popen()? 如果是这样, 可能会刷新未完成的缓冲数据; 如果没有,没有缓冲的数据,所以冲洗是不重要的。

如果管道中有未读的数据,那么这些数据就保留在管道中,供读者收集 – 假设有一个阅读器。

湾 过程正常返回时的标准行为是什么? 是否保证冲洗管道并关闭管道? (当然没有明确这样做)。

这取决于管道是否通过标准I / O连接。 如果没有,没有任何悬而未决的。 如果是这样,那么是的,当标准I / O流关闭时,缓冲区中的任何材料都将被刷新。


C。 感谢信号和未读数据的信息,但是我对标准I / O管道连接有点困惑。 在你提到popen()之后,我查了一下,手册页说它的返回值与I / O流相同,并且这些流默认是完全缓冲的。 我只是不清楚两者之间的差异,也不明白差异来自哪里。

管道创建的基本系统调用是pipe(2) 。 它创建两个文件描述符,一个用于管道的读取端,一个用于写入端。 如果你对它们什么都不做,那么它们仍然是文件描述符,没有缓冲的输出(通过write(2)和相关的系统调用)。 如果进程终止,应用程序中没有缓冲区; 管道关闭。

如果你使用popen(3) ,那么它会为你做更多的工作。 它仍然调用pipe(2)来创建管道,但它然后做一个fork(2) 。 孩子安排正确的管道配置并启动子进程。 父母也关闭未使用的管道末端,并使用fdopen(3)为调用进程创建一个标准的I / O文件流。

对于文件流,如果I / O缓冲区中有数据,则关闭或等效将确保未完成的数据被刷新并且文件描述符被关闭。

正常的行为是所有文件描述符在进程终止时都关闭。 这意味着一个管道就像任何其他打开的文件描述符一样正常关闭。

有一个关于管道的有趣的事情:在POSIX中,如果一个进程写入一个已关闭的管道,作者将得到一个SIGPIPE信号。


编辑:

需要注意的是:SIGx终止和普通终止的不同之处在于,像任何其他文件写入一样,您可能会丢失已经缓存(通过FILE写入)但尚未写入文件描述符的数据。