Maison > Article > développement back-end > Comment éviter les blocages de Readline lors de l'arrêt de la sortie du processus en Python ?
Description du problème :
Dans un programme Python utilisant os.popen () ou subprocess.Popen() pour lire le résultat d'un processus de mise à jour continue (comme top), le programme peut se bloquer lors de la tentative de lecture de toutes les lignes à l'aide de readlines().
Utilisation d'un fichier temporaire et d'un processus enfant :
<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>
Cette approche utilise un fichier temporaire pour stocker la sortie du processus, permettant au programme d'éviter le blocage sur readlines().
Utilisation d'une file d'attente avec un autre fil de discussion :
<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>
Utilisation de 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>
Ces alternatives permettent au programme de continuer à s'exécuter tout en enregistrant le résultat du processus. Ils peuvent être plus appropriés dans les cas où vous devez surveiller en permanence le résultat du processus.
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!