簡體   English   中英

從線程中的子進程標准輸出讀取時的隨機行為

[英]Random behaviour while reading from subprocess stdout in a thread

我正在編寫一個腳本來啟動一個進程並檢查它的標准輸出(當它正在運行時,而不是在執行結束時)。

顯而易見的選擇似乎有一個線程,該線程將被阻止從進程標准輸出讀取行。

我已經使用 WSL2 bash 對其進行了測試:

python __main__.py 'echo ok'

結果是隨機的,導致以下情況之一:

  • 執行終止,沒有任何輸出
  • “ok”按預期打印
  • “ok”打印后跟一個 'ValueError: readline of closed file' 異常

關於可能是什么問題的任何想法?

編碼:

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.

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