Heim  >  Artikel  >  Backend-Entwicklung  >  Wie vermeide ich Readline-Hänge beim Stoppen der Prozessausgabe in Python?

Wie vermeide ich Readline-Hänge beim Stoppen der Prozessausgabe in Python?

Patricia Arquette
Patricia ArquetteOriginal
2024-10-30 08:44:02277Durchsuche

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

Vermeiden von Readline-Hängen beim Stoppen der Prozessausgabe in Python

Problembeschreibung:

In einem Python-Programm mit os.popen () oder subprocess.Popen() verwenden, um die Ausgabe eines sich ständig aktualisierenden Prozesses (z. B. top) zu lesen, kann das Programm hängen bleiben, wenn versucht wird, alle Zeilen mit readlines() zu lesen.

Lösung:

Verwenden einer temporären Datei und eines untergeordneten Prozesses:

<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>

Dieser Ansatz verwendet eine temporäre Datei zum Speichern der Prozessausgabe, sodass das Programm eine Blockierung bei readlines() vermeiden kann.

Alternative Lösungen:

Verwenden einer Warteschlange mit einem anderen Thread:

<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>

Verwenden von 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>

Diese Alternativen ermöglichen es dem Programm, weiterzulaufen und gleichzeitig die Prozessausgabe zu speichern. Sie eignen sich möglicherweise besser für Fälle, in denen Sie die Prozessausgabe kontinuierlich überwachen müssen.

Das obige ist der detaillierte Inhalt vonWie vermeide ich Readline-Hänge beim Stoppen der Prozessausgabe in Python?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn