我试图了解命名管道的工作原理,以便简化单向进程间通信。我预计会由于将数据复制到循环缓冲区而产生一些开销,我本以为它存储在RAM中,因此我希望管道比写入文件快得多(因为RAM比磁盘快几个数量级)。
相反,我发现命名管道(或匿名管道)与文件的速度大致相同。这是在运行普通Linux并具有普通磁盘驱动器(非固态)的3 GHz桌面上。这是Python中的简化测试程序:
import sys
import time
import random
megabyte = "".join(random.choice("abcdefghijklmnopqrstuvwxyz") for x in range(1024**2))
while True:
before = time.time()
sys.stdout.write(megabyte)
after = time.time()
sys.stderr.write("{} microseconds\n".format(1e6 * (after - before)))
管道直达/dev/null
:
python test.py > /dev/null
每兆字节产生2.1微秒(恒定)。
管道到文件:
python test.py > /tmp/testout.txt
在500微秒和930微秒之间跳转(随着文件变大,这个值越来越普遍-大概是在寻找磁盘空间)。
然后是命名管道:
mkfifo testpipe
cat testpipe > /dev/null &
python test.py > testpipe
产生640微秒(恒定)和未命名的管道:
python test.py | cat > /dev/null
还产生650微秒(恒定)。
谁能解释为什么管道的速度更像文件的速度而不是/dev/null
速度?我可能在某处有一个开关,说“通过基于文件的缓冲区而不是基于RAM的缓冲区运行管道”,我可以更改该开关吗?可能是内核选项还是shell变量?
另一种解释:假设磁盘输出在500到930微秒之间跳跃,因为500只是管道传输而930实际上正在写入。那么在两种情况下用于管道的500〜640是等效的。但是,根据这种解释,为什么管道和实际写入磁盘之间只有两个因数? 谈论RAM磁盘的网站说,RAM磁盘的速度是硬盘的50-200倍。
/dev/null
实际上是很便宜的,而在其他任何地方写入(无论是文件,FIFO,管道还是其他任何东西)则要贵得多,因为它需要“大量”的处理工作。