2016-05-19 3 views
0

サブプロセスを処理するときのメモリ使用量を "バックグラウンド"で理解したいと思います。ここに簡単な例があります。Pythonでパイプされたサブプロセスstdoutから行を読み込むときのメモリ使用

版画「こんにちは」は、その後10Sと版画「世界」を待って、次のスクリプトtest.py考える:次に

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

次のスクリプトtest_sub.pyがサブプロセス「test.py」と呼びますが、標準出力にリダイレクト私はそれがサブプロセスの呼び出しをした後、それは「世界は」来るまで「こんにちは」その後、10秒を待って印刷しますtest_sub.py実行したときに、私の質問は以下のようになり、この場合

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

:パイプは、その後、行ずつそれを読みますそれからiを印刷するt、待っている10の間に "こんにちは"に何が起こるのですか?それはtest_sub.pyが終了するまでメモリに格納されますか、それとも最初の繰り返しで捨てられますか?

これはこの例では問題にならないかもしれませんが、本当に大きなファイルを扱う場合はそうです。

答えて

1

待機中の10分間に「こんにちは」が発生しますか?

"Hello".readline()が二度目すなわちprint("World")の出力を親に読み込まれるまで、"Hello"最低限で命を返すまで(親に)line名を介して利用可能です。

あなたは子プロセスで何が起こるかを意味するならば、sys.stdout.flush()後に生き続けるために"Hello"オブジェクトのための理由はないが、それは例えば、Does Python intern strings?

は、それがtest_sub.pyまでメモリに格納されますない表示される場合があり終了するか、最初の反復で捨てられますか? .readline()

第二時間を返し、line"World"を指します。それはすなわち、特定のPython実装でガベージコレクションに依存した後に何がline"World"場合でも、"Hello"で起こります。オブジェクト"Hello"はしばらくの間生き続けるかもしれません。 Releasing memory in Python

あなたはPYTHONDUMPREFS=1 ENVVARを設定し、pythonプロセスが終了したときに生きているオブジェクトを参照するために、デバッグpythonビルドを使用してコードを実行することができます。たとえば、次のコードを考えてみます。

#!/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) 

それはline第二yieldまでリバウンドされていないことを示しています。 PYTHONDUMPREFS=1 ./python . |& grep "'hello'"の出力 は、pythonが終了すると、'hello'がまだ生きていることを示しています。

関連する問題