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
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