[英]How to send STDIN twice to Popen process, each time with EOF?
我有這部分代碼:
for stdin in stdins:
p.stdin.write(stdin)
它將字符串stdin
寫入處理p
的標准輸入。
挑戰在於:進程p
期望在進入下一個 STDIN 之前看到 EOF。
對於上面的循環,問題在於后續的p.stdin.write(stdin)
將被進程p
視為第一個 STDIN 輸入集合的輸入。 因為,如前所述, p
希望在移動到后續字段之前看到 EOF。
所以,我的問題是:如何在 Python 中解決這個問題? 該過程需要看到如下內容:
for stdin in stdins:
p.stdin.write(stdin)
p.stdin.send_eof()
約束:解決方案不得使用 pexpect。
EOF 不是一個字符,它只是意味着沒有更多的數據要讀取。
因此,我不相信在 Python 或大多數其他語言中你所追求的是可能的。
當我嘗試在 python 中使用多個子進程進行異步渲染時遇到了同樣的問題,這些子進程需要以低延遲與主進程通信。
當我將subprocess.popen()
與stdin=subprocess.PIPE
subprocess.PIPE 一起使用時,我發現子進程在stdin.close()
發生或主進程退出之前無法獲取任何內容,兩者都發送 EOF 信號但使 PIPE 一次性。 當然,我嘗試過stdin.writelines()
、 stdin.flush()
、 pickle.dump()
等,但它們都沒有奏效。
但是有一種方法可以使用NumPy與子進程重復通信。
ndarray.tofile可以直接將數組發送到文件 object。 盡管文檔聲明它等同於 file.write(a.tobytes()) ,但它確實有意義。 我很困惑,直到我在文檔頁面的末尾讀到這個:
當fid為文件object時,直接將數組內容寫入文件,繞過文件對象的write方法。 因此,tofile 不能與支持壓縮的文件對象(例如 GzipFile)或不支持 fileno() 的類文件對象(例如 BytesIO)一起使用。
實際上,我認為這是file.write()
的錯。 任何調用write()
方法的 function 都不可避免地無法發送 EOF,除非我們繞過write()
方法,如果不使用 C 擴展,例如 Z3B7F949B2343F9E53780E29F6EFZ5E1,這是不可能的。
通過 PIPE 發送一般數據現在有兩種方式:
NumPy 支持 dtype dtype=object
,這意味着您可以直接將消息打包到 object 數組中。 另請參閱numpy.lib.format 。
存儲 object arrays,即 arrays 包含任意 ZA7F5F35426B927411FC9231B56 對象的元素帶有 object arrays 的文件不可映射,但可以讀取和寫入磁盤。
如果消息具有常規模式,您可以將 state 結構作為數據類型來打包您的消息,這就是我的情況。 這是我的例子。
task = np.dtype([( "index", np.uint8 ), ( "text", np.unicode_, 128 ), ( "color", np.uint8, 2 ), ( "size", np.uint8 )]) for i in range(123): np.empty(1, dtype=task).tofile(s.stdin) # s is the subprocess' name. time.sleep(1)
然后我在子進程中分別成功得到消息123次。
我真的希望這可以幫助你。 因為我花了將近 4 天的時間才找到這個解決方案。 我幾乎正在考慮使用磁盤上的真實文件來完成進程之間的通信——這應該會更慢——但是感謝 NumPy,我的調試終於結束了……
另外,我認為np.save()
發送 EOF 毫無意義。 您可以在 python 控制台中嘗試此操作。
>>> import numpy as np
>>> import sys
>>> a = np.arange(100).reshape(10,10)
>>> a.tofile(sys.stdout.buffer)
... some garbled characters ...
>>> a.tofiler(sys.stdout)
... some garbled characters ...
>>> np.save(sys.stdout.buffer, a)
... some garbled characters ...
>>> np.save(sys.stdout, a)
Traceback (most recent call last):
File "<input>", line 1, in <module>
File "<__array_function__ internals>", line 5, in save
...
TypeError: write() argument must be str, not bytes
原因是sys.stdout.buffer.write()
接受bytes參數,而sys.stdout.write()
接受str 。 因此,使用 array.tofile write sys.stdout
不會導致任何錯誤,表明它沒有調用write()
方法,而np.save()
調用了。 這引發了一個問題,似乎np.fromfile
不支持 dtype dtype=object
模式。 對此感到抱歉。 也許很難通過 pipe 通過進程傳輸動態類型數據,但我聽說在ctype
模塊內部有一些方法可以在進程之間共享 RAM,這可能會有所幫助。
提到我未能在終端中運行上面的腳本(io.UnsupportedOperation: seek) ,但它在 PyCharm 的 python 控制台中運行良好。 我對此一無所知。 也許 PyCharm 的 python 控制台實際上也有 sys.stdin 的代理。
另外,似乎subprocess.PIPE
具有最大緩沖區大小,因此無法傳輸渲染圖像。 作為我的實驗結果,將它們分成塊並沒有幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.