簡體   English   中英

重復寫入STDIN並讀取子進程的STDOUT而不關閉它

[英]Repeatedly write to STDIN and read STDOUT of a Subprocess without closing it

我正在嘗試在Python中使用子進程,以使外部腳本以類似於服務器的方式打開。 外部腳本首先加載模型。 完成此操作后,它將通過STDIN接受請求,並將處理后的字符串返回給STDOUT。

到目前為止,我已經嘗試過

tokenizer = subprocess.Popen([tokenizer_path, '-l', lang_prefix], stdin=subprocess.PIPE, stdout=subprocess.PIPE)

但是,我不能使用

tokenizer.stdin.write(input_string+'\n')
out = self._tokenizer.stdout.readline()

為了通過子過程重復處理input_strings –無論我使用stdout.read()還是stdout.readline() ,out都將是空的。 但是,當我在讀取STDOUT之前用tokenizer.stdin.close()關閉stdin時,它可以工作,但是這關閉了子進程,這不是我想要的,因為在發送另一個請求之前,我必須重新加載整個外部腳本。

有什么方法可以在不關閉和重新打開的情況下以類似於服務器的方式在python中使用子進程嗎?

感謝這個Answer ,我發現必須使用一個從屬句柄才能與子進程正確通信:

master, slave = pty.openpty()
tokenizer = subprocess.Popen(script, shell=True stdin=subprocess.PIPE, stdout=slave)
stdin_handle = process.stdin
stdout_handle = os.fdopen(master)

現在,我可以與子流程通信,而無需通過關閉它

stdin_handle.write(input)
stdout_handle.readline() #gets the processed input

您的外部腳本可能會緩沖其輸出,因此只有在清除子級緩沖區(子級必須自己執行)時,您才能在父級中讀取它。 使它刷新其緩沖區的一種方法可能是關閉輸入,因為然后它以適當的方式終止並在進程中刷新其緩沖區。

如果您可以控制外部程序(即,如果可以對其進行修補),請在產生輸出后插入沖洗。

否則,有時可以通過將程序附加到偽TTY來使程序不緩沖其輸出(許多程序,包括stdlib,都假定當它們的輸出進入TTY時,不希望緩沖)。 但這有點棘手。

暫無
暫無

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

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