2011-07-11 138 views
7

我有一個像下面這樣的結構:鏈POPEN子進程正常

os.mkfifo('pipe.tmp') 
enc = Popen(['encoder', '-i', 'pipe.tmp']) 
cap = Popen(['capture', '-f', 'pipe.tmp']) 

這裏cap是一個過程,通常寫到一個文件(由-f指定的),但我可以得到它的數據噴涌到屏幕通過提供/dev/stdout作爲輸出文件。同樣,enc期望從類文件對象中讀取,並且我可以通過提供-作爲輸入來從管道中讀取它。所以不是在操作系統中使用命名管道,我認爲特殊的文件可能沒有必要,我可以用一個無名管這樣的..

cap = Popen(['capture', '-f', '/dev/stdout'], stdout=PIPE) 
enc = Popen(['encoder', '-i', '-'], stdin=cap.stdout) 
cap.stdout.close() 

(還要注意的產卵的順序顛倒)。我更喜歡這樣做,因爲臨時文件似乎沒有必要,但我有點擔心這個構造是否會按我期望的方式鏈接進程。

  1. /dev/stdoutcap是從OS的實際標準輸出談論不同?也就是說,在輸入管道-enc中,即使其他進程正在與OS上的/ dev/stdout聊天,我是否還會在這兩個進程之間獲得乾淨的數據通道?
  2. 在阻塞/排隊行爲方面會有什麼顯着差異嗎?我認爲在我的第一個例子中,命名管道將是一個緩衝的4096字節,並且如果cap/enc不夠快寫入/讀取,將在任一端阻塞,但如果我錯了,請糾正我。
  3. 是需要產卵或終止的任何特殊順序,還是我應該知道的任何其他陷阱?

回答

1
  1. 的/ dev /標準輸出爲您提供當前進程的標準輸出,所以你應該蠻好用的那個。 (關於/ dev/stdout沒有任何'全局')
  2. 第一個例子中fifo的大小取決於系統的配置(我不確定如何改變它)。但是subprocess.Popen允許你爲它的I/O操作定義緩衝區大小,所以你應該能夠調整它。 更新:稍微研究一下,我發現管道有64kB的限制,不受bufsize參數的影響。不知道如何解決該問題(除了更頻繁地閱讀並手動處理緩衝外)
  3. 對於第二個示例,看起來您需要按照您提供的順序開始,因爲您需要cap.stdout才能使用在開始enc之前。或者,您可以讓這兩個進程斷開連接並手動處理它們之間的通信。