2016-05-19 4 views
0

Ich möchte nur verstehen, was passiert im "Hintergrund" in Bezug auf die Speicherauslastung beim Umgang mit einem subprocess.Popen() Ergebnis und lesen Zeile für Zeile. Hier ist ein einfaches Beispiel.Speicherauslastung beim Lesen von Zeilen aus einem piped Subprozess stdout in Python

das folgende Skript test.py Da prints „Hallo“, dann 10s und druckt „Welt“ wartet:

import sys 
import time 
print ("Hello") 
sys.stdout.flush() 
time.sleep(10) 
print ("World") 

Dann wird das folgende Skript test_sub.py wird als subprocess ‚test.py‘ nennen, leiten Sie den stdout ein Rohr und dann Zeile für Zeile lesen:

import subprocess, time, os, sy 

cmd = ["python3","test.py"] 

p = subprocess.Popen(cmd, 
        stdout=subprocess.PIPE, 
        stderr=subprocess.STDOUT, universal_newlines = True) 

for line in iter(p.stdout.readline, ''): 
    print("---" + line.rstrip()) 

In diesem Fall meine Frage wäre, wenn ich laufe test_sub.py, nachdem es den subprocess Anruf tut, wird es „Hallo“, dann warten 10s bis „Welt“ kommt drucken und dann drucke ich t, Was passiert mit "Hello" während dieser Wartezeit? Wird es gespeichert, bis test_sub.py endet, oder wird es in der ersten Iteration weggeworfen?

Das mag für dieses Beispiel nicht viel bedeuten, aber wenn es um wirklich große Dateien geht, tut es das auch.

Antwort

1

Was passiert mit "Hello" während dieser Wartezeit?

Die "Hello" (in dem übergeordneten) über line Namen verfügbar ist, bis .readline() das zweite Mal zurückkehrt d.h. "Hello" lebt zumindest bis die Ausgabe der print("World") in den übergeordneten gelesen wird.

Wenn Sie meinen, was dann in dem untergeordneten Prozess geschieht nach sys.stdout.flush() gibt es keinen Grund für "Hello" Objekt weiter zu leben, aber es kann zB siehe Does Python intern strings?

Ist es im Speicher, bis test_sub.py gespeichert bekommen endet, oder wird es in der ersten Iteration weggeworfen?

Nach .readline() das zweite Mal zurückkehrt, bezieht sich line zu "World". Was danach mit "Hello" passiert, hängt von der Speicherbereinigung in der spezifischen Python-Implementierung ab, d. H. Selbst wenn line"World" ist; das Objekt "Hello" kann noch einige Zeit leben. Releasing memory in Python.

Sie könnten PYTHONDUMPREFS=1 envvar gesetzt und der Code mit einem Debugpython Build ausführen, Objekt zu sehen, die noch am Leben sind, wenn die python Prozess beendet wird. Betrachten wir zum Beispiel diesen Code:

#!/usr/bin/env python3 
import threading 
import time 
import sys 

def strings(): 
    yield "hello" 
    time.sleep(.5) 
    yield "world" 
    time.sleep(.5) 

def print_line(): 
    while True: 
     time.sleep(.1) 
     print('+++', line, file=sys.stderr) 

threading.Thread(target=print_line, daemon=True).start() 
for line in strings(): 
    print('---', line) 
time.sleep(1) 

Es zeigt, dass line wird erst in der zweiten yield Rebound. Die Ausgabe von PYTHONDUMPREFS=1 ./python . |& grep "'hello'" zeigt, dass 'hello' noch am Leben ist, wenn python beendet wird.

Verwandte Themen