Maison > Article > développement back-end > Comment éviter le blocage des programmes Python lors de la lecture des résultats d'un processus continu ?
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.
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.
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>
Ce code modifié :
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.
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>
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>
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>
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!