Maison  >  Article  >  développement back-end  >  Comment éviter les blocages de Readline lors de l'arrêt de la sortie du processus en Python ?

Comment éviter les blocages de Readline lors de l'arrêt de la sortie du processus en Python ?

Patricia Arquette
Patricia Arquetteoriginal
2024-10-30 08:44:02356parcourir

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

É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().

Solution :

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().

Solutions alternatives :

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!

Déclaration:
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