1

我想打开一个程序来写入命名管道,但是直到有人真正从命名管道中读取它才会写入。这是可以实现的吗?我怎么知道何时读取管道?

4

3 回答 3

2

写入管道实际上会阻塞,直到有人从管道读取

$ mkfifo f
$ printf "%s\n" "a" "b" "c" "d" > f & # on bg otherwise it blocks until someone reads it
$ cat < f
a
b
c
d
[1]+  Done                    printf "%s\n" "a" "b" "c" "d" > f

printf所以你知道在上面的例子中何时读取管道是Done


因此,一旦有人从管道中读取,等待运行命令可以实现为

printf "%s\n" > f && run_some_command

但是如果命令只是向管道发送数据(在这里推测),您可以直接发送数据,因为它们只会在有人从管道读取时发送

some_command > f # will block until f is read from

另一种查找是否以及谁在读取或写入管道的方法是lsof. 尝试

$ lsof f

并且所有f读取或写入的进程都将与其 pid、进程名称、读取或写入操作一起列出。请参阅手册页。

于 2012-07-04T09:01:21.317 回答
1

除了实现锁定文件或其他信号量/标志之外,我认为没有办法判断命名管道是否具有侦听器。但是,您也许能够检测到另一个方向的事物。 Linus Akesson 写了一篇关于使用管道模拟逻辑门的博客文章。(这是一本引人入胜的超级极客读物。)为了实现他的想法,他需要编写一个工具来检查管道是否有数据等待,而无需实际将数据从管道中取出。

您可以获取他的代码,为您的平台编译它,然后拥有一个工具,该工具仅在确认数据正在等待通过它发送时才从管道中读取。在不知道您真正想要实现的目标的情况下,我不知道此解决方案是否适用于您的实际问题。

底线是命名管道没有缓冲,并且在不使用可能特定于平台的黑客的情况下不提供状态指示。要么发送进程等待接收者,要么接收进程等待发送者。

您可能希望使用比命名管道更高级的消息传递系统。

于 2012-07-05T03:04:15.073 回答
0

命名管道在文件系统中是可见的,并且可以像其他文件一样读写:

$ ls -la /tmp/testpipe
prw-r--r-- 1 mitch users 0 2009-03-25 12:06 /tmp/testpipe|

命名管道是通过 mkfifo 或 mknod 创建的:

$ mkfifo /tmp/testpipe
$ mknod /tmp/testpipe p

以下 shell 脚本从管道中读取。如果管道不存在,它首先创建管道,然后循环读取,直到看到“退出”:

#!/bin/bash

pipe=/tmp/testpipe

trap "rm -f $pipe" EXIT

if [[ ! -p $pipe ]]; then
    mkfifo $pipe
fi

while true
do
    if read line <$pipe; then
        if [[ "$line" == 'quit' ]]; then
            break
        fi
        echo $line
    fi
done

echo "Reader exiting"
于 2012-07-04T09:14:32.437 回答