簡體   English   中英

如何在 Python 子進程中立即讀取標准輸出

[英]How to read stdout immediately in Python subprocess

我正在嘗試制作兩個 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在打印之前結束。

有沒有辦法在sys.stdout.write之后立即從test.py打印標准輸出?

為您舉一個例子,您多次閱讀和寫信給孩子(正如您在問題下的評論中所述)。

子進程 ( test.py ) 將:

  • 讀一行
  • 將每個轉換為大寫,然后寫回,
  • 睡眠 2 秒
  • 重復直到沒有更多輸入,然后寫最后一行

主進程( main.py )將:

  • 三次:
    • 向子進程寫入一行輸入
    • 閱讀答案並說出需要多長時間才能得到答案
    • 睡眠 5 秒
  • 最后,使用communicate讀取任何最終 output 並報告此

這是代碼的output,如下所示:

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 - 希望它在 ZAEA23489CE3AACDA943406EBB28E0 上同樣有效,盡管可以測試這個。)

如您所見,無需等待sleep完成即可收到答案。

(顯然,如果父母的睡眠時間減少到大約 2 秒以下,那么孩子在發送數據時將無法准備好接收數據,因此需要等待更多時間才能得到答復。)

使用這種雙向通信,很容易陷入死鎖情況(每個進程都在等待另一個進程做某事)。 為了避免這種情況,每個進程每次只寫入一行,確保它以換行符結束,並立即刷新 output 緩沖區——讀取過程使用readline()准確讀取一行(讀取到換行符)。 然后希望兩者應該保持一致並避免僵局。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM