我只是想了解"背景"在处理subprocess.Popen()结果和逐行读取时的内存使用方面。这是一个简单的例子。
给出以下脚本test.py
,打印" Hello"然后等待10s并打印" world":
import sys
import time
print ("Hello")
sys.stdout.flush()
time.sleep(10)
print ("World")
然后,以下脚本test_sub.py
将作为子流程调用' test.py',将stdout重定向到管道,然后逐行读取:
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())
在这种情况下,我的问题是,当我执行子进程调用后运行test_sub.py
时,它将打印" Hello"然后等待10秒直到" world"然后打印出来,发生了什么"你好"在那10个等待期间?它会在test_sub.py
完成之前存储在内存中,还是在第一次迭代中被抛弃?
对于这个例子来说,这可能并不重要,但是在处理非常大的文件时,它确实如此。
答案 0 :(得分:1)
"你好"在那10个等待期间?
"Hello"
(在父级中)可通过line
名称获得,直到.readline()
第二次返回,即"Hello"
至少生活 直到在父项中读取print("World")
的输出。
如果您的意思是在子流程中发生了什么,那么在sys.stdout.flush()
之后,"Hello"
对象没有理由继续生活,但可能会看到Does Python intern strings?
在test_sub.py完成之前它是否存储在内存中,还是在第一次迭代中被抛弃?
.readline()
第二次返回后,line
引用"World"
。在此之后"Hello"
会发生什么情况取决于特定Python实现中的垃圾收集,即使line
是"World"
;对象"Hello"
可能会继续存在一段时间。 Releasing memory in Python
您可以设置PYTHONDUMPREFS=1
envvar并使用 debug 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'"
的输出
表示'hello'
退出时python
仍然有效。