使用子進程時,執行非阻塞讀取以避免停止父進程至關重要在等待子進程的輸出時。使用 subprocess.Popen 時會出現此問題,其中如果沒有可用數據,則 readline() 會封鎖。
傳統阻塞方法
通常,開發人員使用以下程式碼來讀取從子程序的標準輸出:
p = subprocess.Popen('myprogram.exe', stdout = subprocess.PIPE) output_str = p.stdout.readline()
但是,如果沒有可用數據。
非阻塞解決方案
可靠的跨平台解決方案涉及利用Queue.get_nowait(),如下面的程式碼所示:
import sys from subprocess import PIPE, Popen from threading import Thread try: from queue import Queue, Empty except ImportError: from Queue import Queue, Empty # python 2.x ON_POSIX = 'posix' in sys.builtin_module_names def enqueue_output(out, queue): for line in iter(out.readline, b''): queue.put(line) out.close() p = Popen(['myprogram.exe'], stdout=PIPE, bufsize=1, close_fds=ON_POSIX) q = Queue() t = Thread(target=enqueue_output, args=(p.stdout, q)) t.daemon = True # thread dies with the program t.start() # ... do other things here # read line without blocking try: line = q.get_nowait() # or q.get(timeout=.1) except Empty: print('no output yet') else: # got line # ... do something with line
此方法使用單獨的執行緒將輸出行排入佇列。然後主執行緒可以使用 get_nowait() 檢查佇列是否包含資料而不會阻塞。這種便攜式解決方案允許跨各種作業系統對子進程輸出進行非阻塞讀取。
以上是如何從子程序 PIPE 執行非阻塞讀取?的詳細內容。更多資訊請關注PHP中文網其他相關文章!