Heim > Backend-Entwicklung > Python-Tutorial > Wie vermeide ich das Hängenbleiben von Python-Programmen beim Lesen kontinuierlicher Prozessausgaben?

Wie vermeide ich das Hängenbleiben von Python-Programmen beim Lesen kontinuierlicher Prozessausgaben?

DDD
Freigeben: 2024-11-01 09:47:02
Original
424 Leute haben es durchsucht

How to Avoid Python Programs Hanging When Reading Continuous Process Output?

Das Lesen von Prozessausgaben in Python ohne Hänge stoppen

Hintergrund

Bei Verwendung der Python-Funktion os.popen() mit Tools, die eine kontinuierliche Ausgabe erzeugen, wird die Das Programm bleibt oft hängen, wenn versucht wird, die Ausgabe zu lesen.

os.popen()-Problem

Die problematische Zeile „process = os.popen("top").readlines() stoppt das Programm aufgrund von readlines(), das versucht, die gesamte Prozessausgabe auf einmal zu lesen.

Lösung mit subprocess.Popen()

Um dieses Problem zu beheben, verwenden Sie subprocess.Popen() anstelle von os.popen (). Hier ist ein korrigiertes Beispiel:

<code class="python">import subprocess
import time
import os

# Start "top" process with stdout redirection
process = subprocess.Popen(["top"], stdout=subprocess.PIPE)

# Wait for 2 seconds
time.sleep(2)

# Send kill signal to "top" process
os.popen("killall top")

# Read process output
output, _ = process.communicate()
print(output.decode())</code>
Nach dem Login kopieren

Dieser geänderte Code:

  • Erfasst die Prozessausgabe in einer Variablen mit communication() anstelle von readlines().
  • Sendet das Kill-Signal an den „obersten“ Prozess.
  • Deklariert das Ende der Datei für den I/O-Stream des Prozesses und beendet das Programm.

Tail-like-Ansatz

Wenn Sie nur einen Teil der Prozessausgabe benötigen, können Sie eine Tail-like-Lösung verwenden, um eine bestimmte Anzahl von Zeilen zu erfassen.

Thread-basierter Ansatz

Zur Prozesserfassung Um die Ausgabe in einem separaten Thread durchzuführen, versuchen Sie Folgendes:

<code class="python">import collections
import subprocess
import threading

# Start process with stdout redirection
process = subprocess.Popen(["top"], stdout=subprocess.PIPE)

# Define function to read process output in a thread
def read_output(process):
    for line in iter(process.stdout.readline, ""):
        ...  # Implement your logic here to process each line

# Create and start a thread for reading and processing output
reading_thread = threading.Thread(target=read_output, args=(process,))
reading_thread.start()

# Wait for 2 seconds, then terminate the process
time.sleep(2)
process.terminate()

# Wait for the reading thread to complete
reading_thread.join()</code>
Nach dem Login kopieren

signal.alarm()-Ansatz

Sie können den Prozess auch mit signal.alarm() nach einem angegebenen Timeout beenden:

<code class="python">import collections
import signal
import subprocess

# Define signal handler
def alarm_handler(signum, frame):
    # Raise an exception to terminate the process reading
    raise Exception

# Set signal handler and alarm for 2 seconds
signal.signal(signal.SIGALRM, alarm_handler)
signal.alarm(2)

# Start process with stdout redirection
process = subprocess.Popen(["top"], stdout=subprocess.PIPE)

# Capture process output
number_of_lines = 200
q = collections.deque(maxlen=number_of_lines)
for line in iter(process.stdout.readline, ""):
    q.append(line)

# Cancel alarm
signal.alarm(0)

# Print captured output
print(''.join(q))</code>
Nach dem Login kopieren

threading.Timer-Ansatz

Alternativ können Sie threading.Timer verwenden, um den Prozessabbruch zu planen:

<code class="python">import collections
import subprocess
import threading

# Define function to terminate the process
def terminate_process(process):
    process.terminate()

# Start process with stdout redirection
process = subprocess.Popen(["top"], stdout=subprocess.PIPE)

# Create and start a timer to terminate process in 2 seconds
timer = threading.Timer(2, terminate_process, [process])
timer.start()

# Capture process output
number_of_lines = 200
q = collections.deque(process.stdout, maxlen=number_of_lines)

# Cancel timer
timer.cancel()

# Print captured output
print(''.join(q))</code>
Nach dem Login kopieren

Das obige ist der detaillierte Inhalt vonWie vermeide ich das Hängenbleiben von Python-Programmen beim Lesen kontinuierlicher Prozessausgaben?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:php.cn
Erklärung dieser Website
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
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage