gpt4 book ai didi

python - 子进程:如果输出之间的时间过长,则无法获得实时输出

转载 作者:行者123 更新时间:2023-12-01 09:10:43 26 4
gpt4 key购买 nike

我想在另一个 python 脚本 (run_python_script.py) 中启动一个 python 脚本(我将其称为 test.py)。为此,我使用 subprocess 命令,如下所示:https://stackoverflow.com/a/18422264 .

这就是run_python_script.py:

import subprocess
import sys
import io
import time


def runPython(filename, filename_log="log.txt"):

with io.open(filename_log, 'wb') as writer, io.open(filename_log, 'rb', 1) as reader:
process = subprocess.Popen("python {}".format(filename), stdout=writer)
while process.poll() is None:
sys.stdout.write(reader.read().decode("utf-8"))
time.sleep(0.5)
# Read the remaining
sys.stdout.write(reader.read().decode("utf-8"))


runPython("test.py")

这是test.py:

import time

sleep_time = 0.0001
start_time = time.time()

for i in range(10000):
print(i)
time.sleep(sleep_time)
print(time.time() - start_time)

在此设置中,实时输出有效,但如果 sleep_time(在 test.py 中)太大,例如 sleep_time = 1run_python_script.py仅在test.py完成后输出。
我将 time.sleep(sleep_time) 替换为其他函数,并且每个需要很长时间的函数都会破坏实时输出。

当然test.py只是一个例子。我想用其他方法,但结果是一样的。

最佳答案

要从子进程获取实时输出,您需要进行一些缓冲区刷新。我假设您使用的是 Python 3,它支持 print 函数的 flush 参数。

我还假设您想将文本数据从子级传递到父级,但传递二进制数据也很容易:摆脱 universal_newlines=True 并更改 bufsize 为零(或适合您的数据的某个缓冲区大小)。

yannick_test.py

from time import sleep, perf_counter

sleep_time = 0.5
start_time = perf_counter()

for i in range(10):
print(i, flush=True)
sleep(sleep_time)

print(perf_counter() - start_time)

run_python_script.py

from subprocess import Popen, PIPE

def run_python(filename):
process = Popen(["python3", filename],
universal_newlines=True, bufsize=1, stdout=PIPE)
for data in process.stdout:
print(data, end='', flush=True)

run_python("yannick_test.py")

典型输出

0
1
2
3
4
5
6
7
8
9
5.0068185229974915
<小时/>

虽然这可行,但构建子脚本会更有效,以便您可以直接导入它们并调用它们的函数,或者如果您需要同时运行,则可以使用线程或多处理。

关于python - 子进程:如果输出之间的时间过长,则无法获得实时输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51670431/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com