Naï*_*ier 6 pipe signals fifo read-write
假设我们有一个名为 的命名管道fifo
,我们正在从两个不同的 shell 读取和写入它。考虑这两个例子:
shell 1$ echo foo > fifo
<hangs>
shell 2$ cat fifo
foo
shell 1$ echo bar > fifo
<hangs>
Run Code Online (Sandbox Code Playgroud)
shell 1$ cat > fifo
<typing> foo
<hangs>
shell 2$ cat fifo
foo
^C
shell 1$
<typing> bar
<exits>
Run Code Online (Sandbox Code Playgroud)
我无法理解这些示例中发生了什么,特别是为什么在第一个示例中尝试将“bar”写入管道会导致阻塞调用,而在第二个示例中它会触发 SIGPIPE。
我知道在第一种情况下,两个单独的进程写入管道,因此它被打开两次,而在第二种情况下,它只被一个进程打开一次并写入两次,进程从管道中读取在此期间被杀害。我不明白的是这如何影响write
.
该pipe(7)
手册页指出:
如果所有引用管道读取端的文件描述符都已关闭,则写入(2) 将导致为调用进程生成 SIGPIPE 信号。
这个条件对我来说听起来不太清楚。一个封闭的文件描述符只是不再是一个文件描述符,对不对?说“管道的读数端已关闭”与“管道的读数端未打开”有何不同?
我希望我的问题足够清楚。顺便说一句,如果你能在详细了解UNIX管道的运作中关系提出的指针open
,close
,read
和write
操作,我会非常感激。
A.B*_*A.B 10
您的示例使用的是fifo
not 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 时死掉,那么从您自己的 C 代码处理 SIGPIPE 的最简单方法是signal(SIGPIPE, SIG_IGN);
通过EPIPE
在每次 write() 之后检查 errno来调用和处理它。