Maison > développement back-end > Tutoriel Python > Comment puis-je empêcher les programmes Python de se bloquer lors de la capture des résultats d'un processus continu ?

Comment puis-je empêcher les programmes Python de se bloquer lors de la capture des résultats d'un processus continu ?

Susan Sarandon
Libérer: 2024-10-29 18:19:09
original
923 Les gens l'ont consulté

How Can I Prevent Python Programs from Hanging When Capturing Continuous Process Output?

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

Lors de l'utilisation de os.popen() pour capturer la sortie du processus, le programme peut se bloquer si le le processus génère continuellement des données. Pour résoudre ce problème, envisagez d'utiliser des méthodes alternatives telles que :

Utilisation de sous-processus et de threads

Démarrez le processus avec subprocess.Popen, créez un fil de discussion pour lire la sortie, et stockez-le dans une file d’attente. Terminez le processus après un délai d'attente spécifique.

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

def read_output(process, append):
    for line in iter(process.stdout.readline, ""):
        append(line)

def main():
    process = subprocess.Popen(["top"], stdout=subprocess.PIPE, close_fds=True)
    try:
        q = collections.deque(maxlen=200)
        t = threading.Thread(target=read_output, args=(process, q.append))
        t.daemon = True
        t.start()
        time.sleep(2)
    finally:
        process.terminate()
    print(''.join(q))</code>
Copier après la connexion

Utilisation du gestionnaire de signaux

Utilisez signal.alarm() pour déclencher une exception après un délai d'attente spécifié. Cela force le processus à se terminer, permettant à la sortie d'être capturée.

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

def alarm_handler(signum, frame):
    raise Alarm

def main():
    process = subprocess.Popen(["top"], stdout=subprocess.PIPE, close_fds=True)
    signal.signal(signal.SIGALRM, alarm_handler)
    signal.alarm(2)
    q = collections.deque(maxlen=200)
    try:
        for line in iter(process.stdout.readline, ""):
            q.append(line)
        signal.alarm(0)
    except Alarm:
        process.terminate()
    finally:
        print(''.join(q))</code>
Copier après la connexion

Utilisation de Timer

Employer threading.Timer pour terminer le processus après un délai d'attente.

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

def main():
    process = subprocess.Popen(["top"], stdout=subprocess.PIPE, close_fds=True)
    timer = threading.Timer(2, process.terminate)
    timer.start()
    q = collections.deque(process.stdout, maxlen=200)
    timer.cancel()
    print(''.join(q))</code>
Copier après la connexion

Approches alternatives

  • Fichier temporaire : Stockez temporairement la sortie du processus dans un fichier, puis lisez-le une fois le processus terminé. tué.
  • Interrogation régulière : Lisez périodiquement la sortie en boucle jusqu'à ce que le processus soit terminé.
  • Flux de sortie non bloquant : Utilisez un bibliothèque qui prend en charge les flux de sortie non bloquants pour éviter les blocages.

Notez que ces solutions peuvent introduire une complexité supplémentaire ou des problèmes de compatibilité. Choisissez l'approche qui convient le mieux à vos besoins spécifiques et à votre plateforme.

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
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal