mkfifo 命令创建命名管道实现进程之间通信

关于mkfifo

mkfifo命令创建一个FIFO特殊文件,是一个命名管道(可以用来做进程之间通信的桥梁)

管道也是一种文件,一般是linux中的一个页大小,4k,管道数据一旦被读取就没了。(管道大小和管道的buff大小理解有错误,请看 pipe-buffer-size-is-4k-or-64k? )

管道是单方向

下面使用命名管道

 

创建管道

hadoop@allin:/data/test1$ mkfifo log.pipe

查看管道

hadoop@allin:/data/test1$ ls -l
total 0
prw-r–r– 1 hadoop hadoop 0 10 14 22:21 log.pipe
仔细看下最前面的部分 开头是 p,表示这是一个管道

使用管道

一对一的情况

#第一个窗口
# ls -l > log.pipe
#第二个窗口
# cat < log.pipe
total 0
prw-r–r– 1 liuzhizhi staff 0 10 14 22:25 log.pipe
这里管道并不是水桶,当我们执行 ls -l > log.pipe 的时候,这里就开始阻塞了,只有当我们再第二个窗口执行 cat < log.pipe 的时候,第一个窗口的ls命令才执行完。
所以这里的管道非常形象,它只是负责传输,虽然它也能存点水,但只有实用的时候才能存住一点水,如果只有一端倒水或者只有一端接水,都是无法正常运行的。

一个输入,多个接收的情况

#窗口1
cat < log.pipe
#窗口2
cat < log.pipe
#窗口3
echo “lzz” > log.pipe
执行的结果是窗口2输出了 lzz,第一个窗没有输出,说明接收方无论多个只能获取一份水,只要被一个接收方接受到,另外一个就无法获取了(所以他不是订阅型的),通过持续往管道输入可以看到,接收方应该是基于抢占式的。

多个输入,一个接受的情况

这里写了一个python程序来做为持续的输入
#coding:utf-8
#logpipe.py
import time
import sys
word = sys.argv[1]
while 1:
    print >> sys.stdout, word
    time.sleep(1)
测试
#窗口1
cat < log.pipe
#窗口2
python logpipe.py win1 > log.pipe
#窗口3
python logpipe.py win2 > log.pipe
#输出
win2
win2
win2
win2
win1
win1
其实这种情况,比较好理解,有个下水道大家都往里面倒水,最后汇总到一个口流出来,由于有缓冲区,所以并不会马上读取到结果。
 

小结

当然我们这里是用bash 操作这个命名管道,其实基本所有的语言都可以使用这个工具,例如bash命令写入管道,python读取,lua读取。
为什么想到这个东西呢,例如实时读取和处理tcpdump抓包,用c来开发成本有点大,用其他语言当然也可以,但是硬件条件有不允许,所以只好通过管道的方式输出到一个非常廉价的小程序来处理喽。

 

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注