假设我们有一个名为的命名管道fifo
,并且正在两个不同的外壳中对其进行读写。考虑以下两个示例:
shell 1$ echo foo > fifo
<hangs>
shell 2$ cat fifo
foo
shell 1$ echo bar > fifo
<hangs>
shell 1$ cat > fifo
<typing> foo
<hangs>
shell 2$ cat fifo
foo
^C
shell 1$
<typing> bar
<exits>
我无法全神贯注于这些示例中发生的事情,尤其是为什么在第一个示例中尝试向管道中写入“ bar”会导致阻塞调用,而在第二个示例中却触发了SIGPIPE。
我确实知道,在第一种情况下,两个单独的进程写入管道,因此打开了两次,而在第二种情况下,它仅由单个进程打开一次并写入了两次,该过程从管道读取同时被杀。我不明白这是如何影响的行为的write
。
该pipe(7)
手册页指出:
如果所有引用管道读取端的文件描述符都已关闭,则写入(2)将导致为调用过程生成SIGPIPE信号。
我觉得这种情况听不清。一个封闭的文件描述符就不再是文件描述符了,对吗?说“管道的读取端已关闭”与“管道的读取端未打开”有何不同?
我希望我的问题足够清楚。顺便说一句,如果你能在详细了解UNIX管道的运作中关系提出的指针open
,close
,read
和write
操作,我会非常感激。
您的示例使用的fifo
不是a pipe
,因此请遵守fifo(7)
。pipe(7)
还告诉:
FIFO(先进先出的缩写)在文件系统中具有名称(使用mkfifo(3)创建),并使用open(2)打开。假设文件权限允许,则任何进程都可以打开FIFO。读取端使用O_RDONLY标志打开;使用O_WRONLY标志打开写端。有关更多详细信息,请参见fifo(7)。注意:尽管FIFO在文件系统中具有路径名,但是FIFO上的I / O不涉及对基础设备的操作(如果有的话)。
管道和FIFO上的I / O管道和FIFO
之间的唯一区别是创建和打开它们的方式。完成这些任务后,管道和FIFO上的I / O具有完全相同的语义。
所以现在从fifo(7)
:
内核为每个至少由一个进程打开的FIFO特殊文件维护一个管道对象。必须先在两端打开FIFO(读取和写入),然后才能传递数据。通常,打开FIFO块,直到另一端也打开。
因此,在打开两端(此处意味着至少有一个阅读器和一个书写器)之前,请根据写入块fifo(7)
。两端都打开后,然后关闭读端,write将根据生成SIGPIPE pipe(7)
。
有关管道用法(而非fifo)的示例,请参见:的示例部分pipe(2)
:涉及pipe()(没有open(),因为pipe()实际上创建了打开的管道对),close(),read()write()和fork()(使用管道时几乎总是有一个fork())。
如果您不希望在写入fifo时死于SIGPIPE,则使用您自己的C代码处理SIGPIPE的最简单方法是signal(SIGPIPE, SIG_IGN);
通过EPIPE
在每个write()之后检查errno来进行调用和处理。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句