簡體   English   中英

如何將 STDIN 兩次發送到 Popen 進程,每次都使用 EOF?

[英]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 發送一般數據現在有兩種方式:

  1. NumPy 支持 dtype dtype=object ,這意味着您可以直接將消息打包到 object 數組中。 另請參閱numpy.lib.format

    存儲 object arrays,即 arrays 包含任意 ZA7F5F35426B927411FC9231B56 對象的元素帶有 object arrays 的文件不可映射,但可以讀取和寫入磁盤。

  2. 如果消息具有常規模式,您可以將 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.

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