小编Rob*_*479的帖子

如果管道在未连接的情况下被删除,则永远打开命名管道块

尝试以下 shell 命令:

mkfifo /tmp/test.pipe

ls -1 /tmp > /tmp/test.pipe &

rm /tmp/test.pipe
mkfifo /tmp/test.pipe
cat /tmp/test.pipe &

jobs
Run Code Online (Sandbox Code Playgroud)

ls命令只是一个示例,可以是任何想要写入命名管道的进程。这里的重点是,该进程将阻止尝试打开管道进行写入。现在,另一个过程出现并移除管道。一个同名的新管道被创建,cat进程(即任何试图打开它进行读取的进程)将阻塞等待另一个进程写入同名的新管道。两个进程都在等待各自的管道连接。这可以通过列出背景来验证jobs

我不太关心阻塞cat(或任何试图从管道读取的进程),因为实际上从管道读取的进程实际上是首先替换它的进程。事实上,我根本不在乎阅读过程。将cat仅用于我的例子来证明的确是又处理指的是同一管道的文件名,但显然是在利用不同的管道实例。但是,请注意,这个死锁示例在相反的情况下也会阻塞,即如果管道被删除而从未打开用于写入,则读取过程将永远阻塞。

我的重点是阻塞写入过程(ls在我的示例中)。它永远没有机会意识到它试图写入的原始管道已被一个新的同名管道替换。

是否有任何 Linux 方法可以识别这种情况,即进程阻止写入对不再存在的命名管道的访问的情况?您可以假定具有 root 权限,并且我知道所有涉及的进程的 PID。特别是,我知道可能会或可能不会遇到这种情况的写作过程。但是,我不知道(这是我想知道的),该进程是否确实遇到了该问题,因此我可以终止它。如何找到阻止访问文件系统上物理上不再存在的命名管道的进程?

显然,ls /proc/<PID>/fd不会列出任一进程对任一管道的访问的文件描述符,除非管道的两端都已连接,即ls /proc/<PID>/fd只有在系统调用成功返回后,才会列出两个进程的管道的文件描述符它的结束。由于在我的示例中有两个不同的同名半连接管道,因此两个进程都没有列出。

process io pipe file-descriptors fifo

5
推荐指数
1
解决办法
1848
查看次数

标签 统计

fifo ×1

file-descriptors ×1

io ×1

pipe ×1

process ×1