从python中的管道子进程stdout读取行时的内存使用情况



我只想了解在处理子流程时,在"后台"内存使用方面会发生什么。Popen()结果并逐行读取。这里有一个简单的例子。

给定打印"Hello"的以下脚本test.py,然后等待10秒并打印"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完成,还是在第一次迭代中被丢弃

对于这个例子来说,这可能并不重要,但在处理真正大的文件时,它确实重要。

在这10秒的等待中,"你好"会发生什么?

"Hello"(在父级中)可通过line名称使用,直到.readline()第二次返回,即"Hello"至少存在,直到在父级读取print("World")的输出。

如果你的意思是子进程中发生了什么,那么在sys.stdout.flush()之后,"Hello"对象没有继续存在的理由,但它可能会例如,参见Python是否实习生字符串?

它是存储在内存中直到testrongub.py完成,还是在第一次迭代中被丢弃?

.readline()第二次返回后,line表示"World"。之后"Hello"会发生什么取决于特定Python实现中的垃圾收集,即即使line"World";对象CCD_ 18可以继续存在一段时间。在Python中释放内存。

您可以设置PYTHONDUMPREFS=1envvar,并使用debugpython构建运行代码,以查看在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)

这表明CCD_ 22直到第二个CCD_。PYTHONDUMPREFS=1 ./python . |& grep "'hello'"的输出表明当CCD_ 26退出时,CCD_。

最新更新