![](/img/trans.png)
[英]Subprocess, repeatedly write to STDIN while reading from STDOUT (Windows)
[英]Random behaviour while reading from subprocess stdout in a thread
我正在編寫一個腳本來啟動一個進程並檢查它的標准輸出(當它正在運行時,而不是在執行結束時)。
顯而易見的選擇似乎有一個線程,該線程將被阻止從進程標准輸出讀取行。
我已經使用 WSL2 bash 對其進行了測試:
python __main__.py 'echo ok'
結果是隨機的,導致以下情況之一:
關於可能是什么問題的任何想法?
編碼:
import argparse
from subprocess import Popen, PIPE
import sys
import threading
class ReadlineThread(threading.Thread):
def __init__(self, proc):
threading.Thread.__init__(self)
self._proc = proc
def run(self):
while self._proc.poll() is None:
line = self._proc.stdout.readline()
sys.stdout.buffer.write(line)
sys.stdout.flush()
def main():
parser = argparse.ArgumentParser()
parser.add_argument('command', nargs='+', help='bar help')
args = parser.parse_args()
with Popen(args.command, stdout=PIPE, stderr=PIPE, shell=True) as proc:
stdout_thread = ReadlineThread(proc)
stdout_thread.start()
if __name__ == "__main__":
main()
當你創建一個線程時,它就成為父進程的一部分。 父進程是運行主函數的線程。 在您的 main 函數中,您調用stdout_thread.start()
,它開始啟動線程的過程,然后立即返回。 之后,您的 main 函數中沒有更多代碼,這導致 python 關閉主進程。 由於您的線程是主進程的一部分,因此當主進程終止時它將被刪除。 同時,您啟動的線程仍在創建中。
這里我們有所謂的競爭條件。 您的線程正在啟動,同時它所屬的進程正在關閉。 如果您的線程設法在進程終止之前啟動並完成其工作,您將獲得預期的結果。 如果進程在線程啟動之前終止,則不會得到任何輸出。 在第三種情況下,進程在線程完成讀取它之前關閉它的標准輸出,從而導致錯誤。
要解決這個問題,在你的 main 函數中,你應該等待生成的線程完成,這可以通過調用stdout_thread.join()
來實現。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.