2011-09-06 163 views
2

我有一個不斷生成數據的子進程,但是大部分數據我都不感興趣,但偶爾在隨機時間,我需要獲取輸出的樣本 - 事情是我需要在明確界定的地方閱讀。例如,我們假設進程每秒產生一個恆定的100字節,有用的信息以100字節爲單位。運行了4秒後,我要求查看100個字節的輸出,然後我會對字節400-499感興趣。但是如果我在4.1秒時問,我不想攔截並得到字節410-509,我需要等待並看到字節500-599。否則,該過程應該愉快地將其輸出流式傳輸到/dev/null我不希望永遠阻止輸出流。我的朋友弗雷德也可能會要求100個字節,比如4.6秒,所以我還需要開始這些東西,並讓數據可供多個消費者閱讀。Python與子進程通信

這種事情有沒有現有的設計模式?我如何使用python子進程實現它,並確保與子進程的通信是非阻塞的?

回答

1

您可能需要不斷地從給定的標準輸出讀取100個字節的數據塊。然後你有一個消費者列表 - 可能只是作爲函數實現字符串/字節串(取決於你是否在2.x或3.x)。每個塊都發送給每個消費者,然後丟棄。

事情是這樣的:

def f_a(s): pass 
def f_b(s): pass 

consumers = [f_a, f_b] 

while True: 
    chunk = process.stdout.read(100) 
    if chunk == '': break # or something like that 
    for c in consumers: c(chunk) 

如果你在一個線程中運行這個,你可以根據你想/需要修改的消費者。

但是你應該注意消費者不要阻止 - 否則你的循環塊。如果它不會持續太久,那就沒有問題,因爲操作系統在你的子進程和你之間給你一個相當大的緩衝區。但它不是無限的。所以可能需要添加一些緩衝,無論是消費者還是循環。

-1
import subprocess 
subProc= subprocess.Popen(['tail','/dev/random'],stdout=subprocess.PIPE) 
subProc.stdout[400:499] ? 

subProc.stdout.seek(400).read(100) 

如果這些不工作。嘗試:

var = subProc.stdout 
var[400:499] 

也擺脫你的子進程適當的輸出,你需要刷新()一旦與Python3.X一段時間,如果我沒有記錯: sys.stdout.flush()

由於一些更奇怪的原因,我沒有任何訪問我的任何UNIX環境,所以我不能真正測試代碼,但理論上這應該做你在問什麼。

+0

好奇:爲什麼downvote? – Tim

+0

我不是downvoter,但很明顯,爲什麼:這兩個建議都無法正常工作。 – wim

2

那麼我是新的python,但似乎proc.communicate或proc.stdout.readline/readlines等待,直到該過程已完成。

據我所知,你可以實現一個輪轉日誌記錄和重定向輸出到一個文件,然後使用子進程可以觸發tailf -n XX日誌文件,在一個循環中直到程序結束,並且每當有一個輸出來自用戶端的請求。