问题描述:
在使用 os.popen 的 Python 程序中() 或 subprocess.Popen() 来读取连续更新进程的输出(例如 top),当尝试使用 readlines() 读取所有行时,程序可能会挂起。
使用临时文件和子进程:
<code class="python">import subprocess import tempfile import time def main(): # Open a temporary file for process output with tempfile.TemporaryFile() as f: # Start the process and redirect its stdout to the file process = subprocess.Popen(["top"], stdout=f) # Wait for a specified amount of time time.sleep(2) # Kill the process process.terminate() process.wait() # Wait for the process to terminate to ensure complete output # Seek to the beginning of the file and print its contents f.seek(0) print(f.read()) if __name__ == "__main__": main()</code>
这种方法使用临时文件来存储进程输出,允许程序避免在 readlines() 上阻塞。
将队列与另一个线程一起使用:
<code class="python">import collections import subprocess import threading def main(): # Create a queue to store process output q = collections.deque() # Start the process and redirect its stdout to a thread process = subprocess.Popen(["top"], stdout=subprocess.PIPE) t = threading.Thread(target=process.stdout.readline, args=(q.append,)) t.daemon = True t.start() # Wait for a specified amount of time time.sleep(2) # Terminate the process process.terminate() t.join() # Wait for the thread to finish # Print the stored output print(''.join(q)) if __name__ == "__main__": main()</code>
使用 signal.alarm():
<code class="python">import collections import signal import subprocess class Alarm(Exception): pass def alarm_handler(signum, frame): raise Alarm def main(): # Create a queue to store process output q = collections.deque() # Register a signal handler to handle alarm signal.signal(signal.SIGALRM, alarm_handler) # Start the process and redirect its stdout process = subprocess.Popen(["top"], stdout=subprocess.PIPE) # Set an alarm to terminate the process after a specified amount of time signal.alarm(2) # Read lines until the alarm is raised or the process terminates try: while True: line = process.stdout.readline() if not line: break q.append(line) except Alarm: process.terminate() # Cancel the alarm if it hasn't already fired signal.alarm(0) # Wait for the process to finish process.wait() # Print the stored output print(''.join(q)) if __name__ == "__main__": main()</code>
这些替代方案允许程序在保存进程输出的同时继续运行。它们可能更适合您需要持续监控流程输出的情况。
以上是在 Python 中停止进程输出时如何避免 Readline 挂起?的详细内容。更多信息请关注PHP中文网其他相关文章!