Maison > développement back-end > Tutoriel Python > Comment éviter le blocage des programmes Python lors de la lecture des résultats d'un processus continu ?

Comment éviter le blocage des programmes Python lors de la lecture des résultats d'un processus continu ?

DDD
Libérer: 2024-11-01 09:47:02
original
453 Les gens l'ont consulté

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

Arrêter la lecture de la sortie du processus en Python sans blocage

Arrière-plan

Lors de l'utilisation de la fonction os.popen() de Python avec des outils qui produisent une sortie continue, le le programme se bloque souvent lorsque vous essayez de lire la sortie.

Problème os.popen()

Le processus de ligne problématique = os.popen("top").readlines() arrête le programme en raison de readlines(), qui tente de lire l'intégralité du résultat du processus en même temps.

Solution avec subprocess.Popen()

Pour résoudre ce problème, utilisez subprocess.Popen() au lieu de os.popen (). Voici un exemple corrigé :

<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>
Copier après la connexion

Ce code modifié :

  • Capture la sortie du processus dans une variable en utilisant communicate() au lieu de readlines().
  • Envoie le signal d'arrêt au processus "top".
  • Déclare la fin du fichier pour le flux d'E/S du processus et quitte le programme.

Approche en forme de queue

Si vous n'avez besoin que d'une partie du résultat du processus, vous pouvez utiliser une solution en forme de queue pour capturer un nombre spécifique de lignes.

Approche basée sur les threads

Pour capturer le processus sortie dans un thread séparé, essayez ce qui suit :

<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>
Copier après la connexion

Approche signal.alarm()

Vous pouvez également utiliser signal.alarm() pour terminer le processus après un délai d'attente spécifié :

<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>
Copier après la connexion

Approche threading.Timer

Vous pouvez également utiliser threading.Timer pour planifier la fin du processus :

<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>
Copier après la connexion

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal