Verwenden Sie communic (), wenn Sie eine Ausgabe in einem Python-Unterprozess empfangen

Eine Notiz für mich, die ich nicht gelesen oder vergessen habe, obwohl sie im Dokument geschrieben war.

Es wird empfohlen, das Unterprozessmodul zu verwenden, wenn untergeordnete Prozesse in Python ausgeführt werden. Wenn Sie "p.stdout.read ()" oder "p.stderr.read ()" verwenden, wenn Sie die Standardausgabe oder Fehlerausgabe dieses untergeordneten Prozesses empfangen Wenn die vom untergeordneten Prozess ausgegebene Datenmenge groß ist, bleibt sie ** hängen **. Es ist eine gute Idee, stattdessen "p.communicate ()" zu verwenden.

Zu diesem Thema in der Mitte des folgenden Dokuments http://docs.python.jp/2.7/library/subprocess.html

Warnung Mit stdin.write (), stdout.read () und stderr.read () kann der OS-Pipe-Puffer einer anderen Pipe gefüllt und ein Deadlock verursacht werden. Verwenden Sie communic (), um dies zu vermeiden.

Es ist geschrieben, aber es ist ein Memo, weil ich es unachtsam verwendet habe (und vom Problem abhängig war).

Unten finden Sie einen einfachen Bestätigungscode.

read () war OK, wenn die Ausgabedatenmenge des untergeordneten Prozesses 10 KB betrug, aber nicht, wenn sie 100 KB betrug. Beide waren mit communic () in Ordnung.

spike.py


import subprocess


def bad_impl(cmd):
    print "start bad_impl %s" % cmd
    p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    print "waiting"
    p.wait()
    stdout_data = p.stdout.read()
    stderr_data = p.stderr.read()
    print "finish: %d %d" % (len(stdout_data), len(stderr_data))
    return p.returncode, stdout_data, stderr_data


def better_impl(cmd):
    print "start better_impl %s" % cmd
    p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    print "waiting"
    stdout_data, stderr_data = p.communicate()
    print "finish: %d %d" % (len(stdout_data), len(stderr_data))
    return p.returncode, stdout_data, stderr_data

command1 = "python -c 'print str(1) * 10000'"           #10 KB Ausgang
command2 = "python -c 'print str(1) * 100000'"          #100 KB Ausgang

better_impl(command1)
print "=" * 50
bad_impl(command1)
print "=" * 50
better_impl(command2)
print "=" * 50
bad_impl(command2)            #Dies schlägt fehl
% python spike.py
start better_impl python -c 'print str(1) * 10000'
waiting
finish: 10001 0
==================================================
start bad_impl python -c 'print str(1) * 10000'
waiting
finish: 10001 0
==================================================
start better_impl python -c 'print str(1) * 100000'
waiting
finish: 100001 0
==================================================
start bad_impl python -c 'print str(1) * 100000'
waiting
↑ Die Steuerung kommt hier nicht zurück

Außerdem,

Der Teil von "communic ()" hat auch die folgende Beschreibung.

Hinweis Die empfangenen Daten werden im Speicher gepuffert. Daher sollten Sie diese Methode nicht verwenden, wenn die zurückgegebenen Daten groß oder uneingeschränkt sind.

Wenn Sie das verfügbare Speicherlimit überschreiten, ist dies ebenfalls nutzlos. In diesem Fall müssen Sie es einzeln vorlesen und in einer Datei speichern. Wenn Sie mit so ein paar GB Daten umgehen, denken Sie zu diesem Zeitpunkt noch einmal darüber nach ... (^^;

Recommended Posts

Verwenden Sie communic (), wenn Sie eine Ausgabe in einem Python-Unterprozess empfangen
Beim Schreiben eines Programms in Python
Verwenden Sie print in Python2 lambda expression
Vorsichtsmaßnahmen beim Beizen einer Funktion in Python
Lesen Sie die Standardausgabe eines Unterprozesses zeilenweise in Python
Ausgabe in Form eines Python-Arrays
Verwenden Sie eine benutzerdefinierte Fehlerseite mit Python / Tornado
[Frage] Was passiert, wenn Sie% in Python verwenden?
Verwenden Sie pydantic beim Lesen von Umgebungsvariablen in Python
Verwenden Sie Datumsangaben in Python
Verwenden Sie Valgrind mit Python
Japanische Ausgabe mit Python
Verwenden Sie den Profiler in Python
Verwenden Sie libsixel, um Sixel in Python auszugeben und das Matplotlib-Diagramm an das Terminal auszugeben.
Das Ausgabe-Timing ist falsch, wenn die Standardausgabe (Fehlerausgabe) in eine Datei in Python konvertiert wird
Ein Memorandum beim Schreiben von experimentellem Code ~ Anmelden in Python
Holen Sie sich die Standardausgabe in Echtzeit mit dem Python-Unterprozess
Beachten Sie beim Initialisieren einer Liste in Python
Was ist in dieser Variablen (wenn das Python-Skript ausgeführt wird)?
Japanische Ausgabe beim Umgang mit Python im Visual Studio
So führen Sie einen Befehl mit einem Unterprozess in Python aus
Eine persönlich verwendete Vorlage zum Erstellen von Discord BOT in Python (Notizen)
Mal sehen, wie def in Python verwendet wird
Machen Sie einen Screenshot in Python
Verwenden Sie den let-Ausdruck in Python
Verwenden Sie das Messprotokoll mit Python
Erstellen Sie eine Funktion in Python
Erstellen Sie ein Wörterbuch in Python
Verwenden Sie die Rückruffunktion in Python
Verwenden Sie den Parameterspeicher in Python
[Python] Verwenden Sie eine Zeichenfolgenfolge
Verwenden Sie den HTTP-Cache in Python
Verwenden Sie in Python ein Diktat mit Listenschlüssel
Verwenden Sie Random Forest mit Python
Verwenden Sie Spyder von Python IDE
Erstellen Sie ein Lesezeichen in Python
Achtung bei os.mkdir in Python
Zeichne ein Herz in Python
Lesen Sie die Fortran-Ausgabe mit Python
[Django] Memorandum, wenn Sie asynchron kommunizieren möchten [Python3]
Verwendung der Methode __call__ in der Python-Klasse
Ändern Sie das Standardausgabeziel in eine Datei in Python
Verhalten beim Angeben einer Liste mit shell = True im Unterprozess
[Python] Hinweise beim Versuch, Numpy mit Cython zu verwenden
Verwenden Sie ein Makro, das beim Speichern von Python mit vscode ausgeführt wird
Ein Hinweis beim Erstellen eines gerichteten Diagramms mit Graphviz in Python
[Selenium] Ändern Sie das Protokollausgabeziel, wenn Sie Phantomjs mit Python3 ausführen
Slack-Benachrichtigung, wenn ein bestimmtes Wort auf Twitter mit Heroku mit Python gemurmelt wird
[Unterprozess] Wenn Sie ein anderes Python-Programm in Python-Code ausführen möchten
Wahrscheinlich in einer Nishiki-Schlange (Originaltitel: Vielleicht in Python)
Konvertieren Sie in eine Zeichenfolge, während Sie die Standardausgabe mit dem Python-Unterprozess ausgeben
Schreiben Sie eine Dichotomie in Python
[Python] Verwalten Sie Funktionen in einer Liste
Vorsichtsmaßnahmen bei der Verwendung von Pit mit Python
Drücken Sie einen Befehl in Python (Windows)
Verwenden Sie Stoff wie in Python (Stoff3)
Erstellen Sie einen DI-Container mit Python
Verhalten beim Auflisten in Python heapq
Verwenden Sie networkx, eine Bibliothek, die Diagramme in Python verarbeitet (Teil 2: Lernprogramm).