Maison >développement back-end >Tutoriel Python >Comment effectuer des lectures non bloquantes à partir d'un PIPE de sous-processus ?

Comment effectuer des lectures non bloquantes à partir d'un PIPE de sous-processus ?

Susan Sarandon
Susan Sarandonoriginal
2024-12-22 15:13:10417parcourir

How to Perform Non-Blocking Reads from a Subprocess PIPE?

Lecture à partir d'un PIPE de sous-processus de manière non bloquante

Lorsque vous travaillez avec des sous-processus, il peut être crucial d'effectuer des lectures non bloquantes pour éviter de bloquer le processus parent. en attendant la sortie du processus enfant. Le problème survient lors de l'utilisation de subprocess.Popen, où readline() bloque s'il n'y a pas de données disponibles.

Approche de blocage traditionnelle

En général, les développeurs utilisent le code suivant pour lire à partir de la sortie standard du sous-processus :

p = subprocess.Popen('myprogram.exe', stdout = subprocess.PIPE)
output_str = p.stdout.readline()

Cependant, cette approche bloque l'exécution si aucune donnée n'est disponible.

Solution non bloquante

Une solution multiplateforme fiable implique l'utilisation de Queue.get_nowait(), comme démontré dans le code ci-dessous :

import sys
from subprocess import PIPE, Popen
from threading  import Thread

try:
    from queue import Queue, Empty
except ImportError:
    from Queue import Queue, Empty  # python 2.x

ON_POSIX = 'posix' in sys.builtin_module_names

def enqueue_output(out, queue):
    for line in iter(out.readline, b''):
        queue.put(line)
    out.close()

p = Popen(['myprogram.exe'], stdout=PIPE, bufsize=1, close_fds=ON_POSIX)
q = Queue()
t = Thread(target=enqueue_output, args=(p.stdout, q))
t.daemon = True # thread dies with the program
t.start()

# ... do other things here

# read line without blocking
try:  line = q.get_nowait() # or q.get(timeout=.1)
except Empty:
    print('no output yet')
else: # got line
    # ... do something with line

Cette approche utilise un thread séparé pour mettre les lignes de sortie en file d'attente dans une file d'attente. Le thread principal peut alors vérifier si la file d'attente contient des données sans blocage, en utilisant get_nowait(). Cette solution portable permet des lectures non bloquantes sur les sorties des sous-processus sur différents systèmes d'exploitation.

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