2013-02-17 96 views
1

perl中的包裝我需要python中的非阻塞子流程(有各種類型的shell io)。另外我對shell的輸出和返回值感興趣。有時候返回值是0,但代碼實際上並沒有做任何事情。
因此,我現在可以使用subprocess.call()(非阻塞但不是shell輸出)或subprocess.Popen()(阻塞但shell輸出)。python中的非阻塞子流程

我做了一些閱讀,但唯一的解決方案看起來像有一個單獨的隊列來做到這一點。更容易我錯過了?

回答

4

subprocess.Popen不是固有的阻塞。您仍然可以使用proc.stdin.write()proc.stdout.read();唯一的問題是,如果管道填滿了,你可能會在一側發生堵塞,甚至發生死鎖[1]。如果您知道您的子進程只會讀取或寫入少量數據,則不必擔心。

所以,你可以這樣做:

proc = subprocess.Popen(['perl', 'somescript.pl'], stdout=subprocess.PIPE) 
buf = StringIO() 
CHUNKSIZE = 1024 # how much to read at a time 

while True: 
    # do whatever other time-consuming work you want here, including monitoring 
    # other processes... 


    # this keeps the pipe from filling up 
    buf.write(proc.stdout.read(CHUNKSIZE)) 

    proc.poll() 
    if proc.returncode is not None: 
     # process has finished running 
     buf.write(proc.stdout.read()) 
     print "return code is", proc.returncode 
     print "output is", buf.getvalue() 

     break 

在一個更大的應用程序,你可以安排這個在你的事件循環,電抗器等發生


[1] OS只能將就允許這麼多的數據一次適合管道。假設你運行cat作爲你的子進程,並向其stdin寫入大量數據。 cat會將這些數據寫入它自己的stdout直到它填滿,然後它會阻塞,直到你的程序從標準輸出中讀取一些數據並清空管道。但是你的程序仍然寫入stdin,並且cat不再讀取它,所以管道也會填滿。這兩個進程都會阻塞寫入,等待另一個進行讀取,這將永遠不會發生。

+0

謝謝,我試試看。不應該是很多數據 – user501743 2013-03-01 22:08:19