关于管道的基本问题

时间:2009-12-24 00:28:01

标签: windows unix pipe

我有一些关于管道的基本问题我不确定。

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

b)如果流程正常返回,标准行为是什么?是否保证冲洗管道并关闭管道? (当然没有明确地这样做)。

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

感谢。

2 个答案:

答案 0 :(得分:2)

  

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

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

如果管道中有未读数据,该数据将保留在管道中,供读者收集 - 假设有读卡器。

  

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

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


  

℃。感谢有关信号和未读数据的信息,但我对标准I / O管道连接有点困惑。在您提到popen()后,我查了一下,手册页说它的返回值与I / O流相同,默认情况下流完全缓冲。我不清楚两者之间的区别,也不了解差异的来源。

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

如果您使用popen(3),那么它会为您完成更多工作。它仍会调用pipe(2)来创建管道,但它会执行fork(2)。孩子安排正确的管道配置并启动子进程。父级还关闭管道的未使用端,并使用fdopen(3)为调用进程创建标准I / O文件流。

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

答案 1 :(得分:1)

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

管道有一个有趣的事情:在POSIX中,如果进程写入已关闭的管道,则编写器将获得一个信号SIGPIPE。

<小时/> 编辑:

警告:s SIGx终止和正常终止之间的区别在于,与任何其他文件写入一样,您可能会丢失已缓冲的数据(通过FILE写入)并且尚未写入文件描述符。