从 python 中的管道子进程标准输出读取行时的内存使用情况
Memory usage when reading lines from a piped subprocess stdout in python
我只想了解 "background" 在处理 subprocess.Popen() 结果和逐行读取时的内存使用情况。这是一个简单的例子。
给定以下脚本 test.py
打印 "Hello" 然后等待 10 秒并打印 "world":
import sys
import time
print ("Hello")
sys.stdout.flush()
time.sleep(10)
print ("World")
然后下面的脚本test_sub.py
将作为子进程'test.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())
在这种情况下,我的问题是,当我 运行 test_sub.py
执行子进程调用后,它将打印 "Hello" 然后等待 10 秒,直到 "world" 出现然后打印出来,在这 10 秒的等待期间 "Hello" 发生了什么?它是存储在内存中直到 test_sub.py
完成,还是在第一次迭代时被丢弃?
对于这个例子来说这可能无关紧要,但是当处理非常大的文件时它就很重要了。
what happens to "Hello" during those 10s of waiting?
"Hello"
(在 parent 中)可通过 line
名称获得,直到 .readline()
returns 第二次,即 "Hello"
在 parent.
中读取 print("World")
的输出之前,至少 还活着
如果你的意思是在 child 过程中发生了什么,那么在 sys.stdout.flush()
之后 "Hello"
object 没有理由继续存在,但它可能例如,看到Does Python intern strings?
Does it get stored in memory until test_sub.py finishes, or does it get tossed away in the first iteration?
第二次.readline()
returns后,line
指的是"World"
。 "Hello"
之后会发生什么取决于特定 Python 实现中的垃圾收集,即,即使 line
是 "World"
; object "Hello"
可能还会继续活一段时间。 Releasing memory in Python.
您可以使用 debug python
构建设置 PYTHONDUMPREFS=1
envvar 和 运行 您的代码,以查看 object当 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'
仍然存在。
我只想了解 "background" 在处理 subprocess.Popen() 结果和逐行读取时的内存使用情况。这是一个简单的例子。
给定以下脚本 test.py
打印 "Hello" 然后等待 10 秒并打印 "world":
import sys
import time
print ("Hello")
sys.stdout.flush()
time.sleep(10)
print ("World")
然后下面的脚本test_sub.py
将作为子进程'test.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())
在这种情况下,我的问题是,当我 运行 test_sub.py
执行子进程调用后,它将打印 "Hello" 然后等待 10 秒,直到 "world" 出现然后打印出来,在这 10 秒的等待期间 "Hello" 发生了什么?它是存储在内存中直到 test_sub.py
完成,还是在第一次迭代时被丢弃?
对于这个例子来说这可能无关紧要,但是当处理非常大的文件时它就很重要了。
what happens to "Hello" during those 10s of waiting?
"Hello"
(在 parent 中)可通过 line
名称获得,直到 .readline()
returns 第二次,即 "Hello"
在 parent.
print("World")
的输出之前,至少 还活着
如果你的意思是在 child 过程中发生了什么,那么在 sys.stdout.flush()
之后 "Hello"
object 没有理由继续存在,但它可能例如,看到Does Python intern strings?
Does it get stored in memory until test_sub.py finishes, or does it get tossed away in the first iteration?
第二次.readline()
returns后,line
指的是"World"
。 "Hello"
之后会发生什么取决于特定 Python 实现中的垃圾收集,即,即使 line
是 "World"
; object "Hello"
可能还会继续活一段时间。 Releasing memory in Python.
您可以使用 debug python
构建设置 PYTHONDUMPREFS=1
envvar 和 运行 您的代码,以查看 object当 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'
仍然存在。