Python子程序readlines()掛起問題
可以實作串流傳輸檔案並逐行列印檔案輸出使用各種方法。然而,使用帶有 readlines() 的子程序可能會導致掛起問題。
考慮設計用於串流 Ruby 檔案「ruby_sleep.rb」的 Python 腳本「main.py」和列印其輸出。
import pty import os from subprocess import Popen, PIPE, STDOUT file_path = '/path/to/ruby_sleep.rb' command = ' '.join(["ruby", file_path]) master, slave = pty.openpty() proc = Popen(command, bufsize=0, shell=True, stdout=slave, stderr=slave, close_fds=True) stdout = os.fdopen(master, 'r', 0) while proc.poll() is None: data = stdout.readline() if data != "": print(data) else: break print("This line is never reached")
執行此腳本按預期流式傳輸Ruby 輸出,但readline() 方法無限期掛起,導致「永遠無法到達此行」字串永遠不會被列印。
已提出各種解決方案來解決此掛起問題:
Stdbuf 可以在非交互模式下啟用行緩衝。
from subprocess import Popen, PIPE, STDOUT proc = Popen(['stdbuf', '-oL', 'ruby', 'ruby_sleep.rb'], bufsize=1, stdout=PIPE, stderr=STDOUT, close_fds=True) for line in iter(proc.stdout.readline, b''): print line, proc.stdout.close() proc.wait()
Pexpect 可用於基於行的控制。
import pexpect pexpect.run("ruby ruby_sleep.rb", logfile=sys.stdout)
PTY 允許提供 tty 以在 Ruby 端啟用行緩衝。
import os import pty from subprocess import Popen, STDOUT master_fd, slave_fd = pty.openpty() proc = Popen(['ruby', 'ruby_sleep.rb'], stdin=slave_fd, stdout=slave_fd, stderr=STDOUT, close_fds=True) os.close(slave_fd) while 1: try: data = os.read(master_fd, 512) except OSError as e: if e.errno != errno.EIO: raise break # EIO means EOF on some systems else: if not data: # EOF break print('got ' + repr(data)) finally: os.close(master_fd) if proc.poll() is None: proc.kill() proc.wait() print("This is reached!")
以上是為什麼 Python 的 `subprocess.Popen` 和 `readlines()` 會掛起,如何修復它?的詳細內容。更多資訊請關注PHP中文網其他相關文章!