python - 如何在 Python 子进程中立即读取标准输出
问题描述
我正在尝试制作两个 python 进程。
主文件
child = Popen(['python.exe', 'test.py'], stdin=PIPE, stdout=PIPE, stderr=STDOUT)
stdout, stderr = child.communicate(input='hello world'.encode())
result = stdout.decode()
print(result)
测试.py
value = sys.stdin.read()
sys.stdout.write(value)
time.sleep(10)
(time.sleep 只是一个耗时任务的例子。)
在这种情况下,打印前main.py
等待 10 秒test.py
以结束。
有没有办法在test.py
之后立即打印标准输出sys.stdout.write
?
解决方案
为您举一个例子,您多次阅读和写信给孩子(正如您在问题下的评论中所述)。
子进程 ( test.py
) 将:
- 读一行
- 将每个转换为大写,然后写回,
- 睡眠 2 秒
- 重复直到没有更多输入,然后写最后一行
主进程 ( main.py
) 将:
- 三次:
- 向子进程写入一行输入
- 阅读答案并说出需要多长时间才能得到答案
- 睡眠 5 秒
- 最后,使用 读取任何最终输出
communicate
,并报告此内容
这是代码的输出,如下所示:
writing to child: hello world 0
child replied with: HELLO WORLD 0
got answer back within 0.00022 seconds
writing to child: hello world 1
child replied with: HELLO WORLD 1
got answer back within 0.00012 seconds
writing to child: hello world 2
child replied with: HELLO WORLD 2
got answer back within 0.00021 seconds
final output from child: finishing
这是代码:
test.py
import sys
import time
while True:
value = sys.stdin.readline()
if not value:
break
sys.stdout.write(value.upper())
sys.stdout.flush()
time.sleep(2)
sys.stdout.write("finishing\n")
main.py
from subprocess import Popen, PIPE, STDOUT
import time
child = Popen(['python.exe', 'test.py'], stdin=PIPE, stdout=PIPE, stderr=STDOUT)
time.sleep(1)
for i in range(3):
data_in = f"hello world {i}"
print(f"writing to child: {data_in}")
time0 = time.time()
child.stdin.write(f"{data_in}\n".encode())
child.stdin.flush()
data_out = child.stdout.readline()
time1 = time.time()
result = data_out.decode().strip()
elapsed_time = time1 - time0
print(f"child replied with: {result}")
print(f"got answer back within {elapsed_time:.5f} seconds\n")
time.sleep(5)
output, error = child.communicate()
print(f"final output from child: {output.decode()}")
(在 Linux 上使用python
而不是测试python.exe
- 希望它在 Windows 上同样有效,尽管我无法测试。)
如您所见,无需等待sleep
完成即可收到答案。
(显然,如果父母的睡眠时间减少到大约 2 秒以下,那么孩子在发送数据时将无法接收数据,因此需要等待更多时间才能得到答复。)
通过这种双向通信,很容易陷入死锁情况(每个进程都在等待另一个进程做某事)。为避免这种情况,每个进程每次只写入一行,确保它以换行符结束,并立即刷新输出缓冲区 - 读取过程用于readline()
读取准确的一行(读取直到换行)。然后希望两者应该保持一致并避免僵局。
推荐阅读
- batch-file - 如何在 dir 命令中获取最后一个文件名?
- javascript - GroupMe 提及 API
- mysql - 简单的 Eloquent 查询执行时间过长
- networking - 如何通过 office 代理从 nodemcu 建立到 adafruit 的 mqtt 连接?
- swagger-ui - 命令行“找不到匹配项:connexion [swagger-ui]”
- python - 具有单个列表元素的列表列表的平方差总和
- c# - C# .NET async/await 报告进度而不到处传递 IProgress?
- ios - 如何在tableview中列出数据
- wordpress - 如何全局使用 wp_localize_script() Ajax URL
- excel - 如何在下拉列表 Excel 中增加字体大小