停止在Python 中讀取進程輸出而不掛起
當使用os.popen() 捕獲進程輸出時,如果出現以下情況,程式可能會掛起:過程不斷輸出資料。要解決此問題,請考慮使用替代方法,例如:
使用子進程和執行緒
使用subprocess.Popen 啟動進程,並建立一個執行緒來讀取輸出,並將其儲存在佇列中。在特定超時後終止進程。
<code class="python">import subprocess import threading import time def read_output(process, append): for line in iter(process.stdout.readline, ""): append(line) def main(): process = subprocess.Popen(["top"], stdout=subprocess.PIPE, close_fds=True) try: q = collections.deque(maxlen=200) t = threading.Thread(target=read_output, args=(process, q.append)) t.daemon = True t.start() time.sleep(2) finally: process.terminate() print(''.join(q))</code>
使用訊號處理程序
使用 signal.alarm() 在指定超時後引發異常。這會強制進程終止,從而捕獲輸出。
<code class="python">import signal import subprocess import time def alarm_handler(signum, frame): raise Alarm def main(): process = subprocess.Popen(["top"], stdout=subprocess.PIPE, close_fds=True) signal.signal(signal.SIGALRM, alarm_handler) signal.alarm(2) q = collections.deque(maxlen=200) try: for line in iter(process.stdout.readline, ""): q.append(line) signal.alarm(0) except Alarm: process.terminate() finally: print(''.join(q))</code>
使用計時器
使用執行緒。計時器在超時後終止進程。
<code class="python">import threading import subprocess def main(): process = subprocess.Popen(["top"], stdout=subprocess.PIPE, close_fds=True) timer = threading.Timer(2, process.terminate) timer.start() q = collections.deque(process.stdout, maxlen=200) timer.cancel() print(''.join(q))</code>
替代方法
請注意,這些解決方案可能會引入額外的複雜性或相容性問題。選擇最適合您的特定需求和平台的方法。
以上是如何防止Python程式在捕捉連續進程輸出時掛起?的詳細內容。更多資訊請關注PHP中文網其他相關文章!