停止在 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中文网其他相关文章!