首页  >  文章  >  后端开发  >  在 Python 中停止进程输出时如何避免 Readline 挂起?

在 Python 中停止进程输出时如何避免 Readline 挂起?

Patricia Arquette
Patricia Arquette原创
2024-10-30 08:44:02277浏览

How to Avoid Readline Hangs When Stopping Process Output in Python?

在 Python 中停止进程输出时避免 Readline 挂起

问题描述:

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

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn