【linux】mkfifo 命令建立命名管道實現程序之間通訊
阿新 • • 發佈:2019-02-04
mkfifo 命令
- mkfifo命令建立一個FIFO特殊檔案,是一個命名管道(可以用來做程序之間通訊的橋樑)
- 管道也是一種檔案,一般是linux中的一個頁大小,4k,管道資料一旦被讀取就沒了。(管道大小和管道的buff大小理解有錯誤,請看 pipe-buffer-size-is-4k-or-64k? )
- 管道是單方向
使用命名管道
下面均是再OSX系統實驗。
建立管道
liuzhizhi@lzz-rmbp|pipe # mkfifo log.pipe
檢視管道
liuzhizhi@lzz-rmbp|pipe # ls -l
total 0
prw-r--r-- 1 liuzhizhi staff 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來開發成本有點大,用其他語言當然也可以,但是硬體條件有不允許,所以只好通過管道的方式輸出到一個非常廉價的小程式來處理嘍。