Heim >Backend-Entwicklung >Python-Tutorial >Wie führe ich nicht blockierende Lesevorgänge aus einer Subprozess-PIPE durch?

Wie führe ich nicht blockierende Lesevorgänge aus einer Subprozess-PIPE durch?

Susan Sarandon
Susan SarandonOriginal
2024-12-22 15:13:10372Durchsuche

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

Nicht blockierendes Lesen aus einer Unterprozess-PIPE

Bei der Arbeit mit Unterprozessen kann es entscheidend sein, nicht blockierende Lesevorgänge durchzuführen, um ein Abwürgen des übergeordneten Prozesses zu vermeiden während auf die Ausgabe des untergeordneten Prozesses gewartet wird. Das Problem tritt auf, wenn subprocess.Popen verwendet wird, wo readline() blockiert, wenn keine Daten verfügbar sind.

Traditioneller Blockierungsansatz

Normalerweise verwenden Entwickler zum Lesen den folgenden Code aus der Standardausgabe des Unterprozesses:

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

Dieser Ansatz blockiert jedoch die Ausführung, wenn keine Daten vorhanden sind verfügbar.

Nicht blockierende Lösung

Eine zuverlässige plattformübergreifende Lösung beinhaltet die Verwendung von Queue.get_nowait(), wie im folgenden Code gezeigt:

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

Dieser Ansatz verwendet einen separaten Thread, um Ausgabezeilen in eine Warteschlange einzureihen. Der Hauptthread kann dann mithilfe von get_nowait() prüfen, ob die Warteschlange Daten enthält, ohne zu blockieren. Diese tragbare Lösung ermöglicht nicht blockierende Lesevorgänge auf Unterprozessausgaben auf verschiedenen Betriebssystemen.

Das obige ist der detaillierte Inhalt vonWie führe ich nicht blockierende Lesevorgänge aus einer Subprozess-PIPE durch?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn