2011-02-12 23 views
5

問題:將gevent和multiprocessing結合在一起與子進程進行通信

我可以使用multiprocessing模塊和Windows上的gevent以高效的方式嗎?

場景:

我有一個基於GEVENT Python應用程序在Windows上執行異步I/O。該應用程序主要是I/O綁定,但也有更高CPU負載的尖峯。此應用程序需要通過其stdin和stdout控制控制檯應用程序。我無法修改此控制檯應用程序,用戶將能夠使用他自己的自定義應用程序,只有基於文本(行)的通信協議已修復。

我有使用子和線程工作的實施,但我寧願用這些線程一起推動整個子基於通信的代碼放到一個單獨的進程中打開主應用程序恢復到單線程的。我打算爲此使用多處理模塊。

前閱讀:

我一直在網上搜索了很多,看了一些源代碼,所以我知道,多模塊使用基於Windows上命名管道一個管道實現。一對multiprocessing.queue.Queue對象將用於與第二個Python進程進行通信。這些隊列基於該管道實施,例如, IPC將通過命名管道完成。

關鍵的問題是,是否調用輸入隊列的get方法會阻止GEVENT的主循環與否。這種方法有一個超時,所以我可以把它變成一個有小超時的循環,但這不是一個好的解決方案,因爲它仍然會阻止小時間段內的危機,從而損害其低I/O延遲。

我也願意就如何規避使用Windows,這是衆所周知的是硬,有時脆弱管道的整個問題的建議。我不確定基於共享內存的IPC是否可以在Windows上使用。也許我可以用一種方式來包裝控制檯應用程序,這樣可以使用網絡套接字與子進程進行通信,這種方法已知可以和gevent很好地協作。

請不要如果可能的話質疑我的基本用例。謝謝。

+0

我發現了一個適合在Windows和UNIX上異步讀取和寫入子過程管道的模塊。它可以與gevent的事件循環集成以獲得相當通用的解決方案:http://code.activestate.com/recipes/440554-module-to-allow-asynchronous-subprocess-use-on-win/ – fviktor 2011-04-08 20:50:07

回答

1

隊列的get方法實在是堵。在超時時使用它可能會解決您的問題,但它絕對不會是最乾淨的解決方案,而且最重要的解決方案將導致額外的延遲,因爲沒有理由。即使它沒有阻塞,那也不是一個好的解決方案。僅僅因爲非阻塞本身是不夠的,好的異步調用/ API應該平滑地集成到使用中的I/O框架中。是Python的gevent,適用於C++的libevent或用於C++的Boost ASIO。

最簡單的解決辦法是通過生成您的控制檯應用程序並安裝到其控制檯和退出描述使用簡單的I/O。有兩個主要因素需要考慮:

  • 對於客戶編寫客戶端應用程序將非常容易。他們不需要使用任何種類的IPC,套接字或其他代碼,這對很多人來說都是非常困難的。通過這種方法,應用程序將從標準輸入讀取並寫入標準輸出。
  • 使用此方法測試控制檯應用程序非常容易,因爲您可以手動啓動它們,將文本輸入到控制檯並查看結果。
  • Gevent非常適合異步讀/寫在這裏。

然而,缺點是你將不得不啓動這個應用程序,將不支持與它的併發通信,並且將不支持通過網絡進行通信。甚至有一個good example for starters

爲了簡單但更靈活,您可以使用TCP/IP套接字。如果客戶端和服務器都在同一臺計算機上運行。另外,一個好的操作系統將使用IPC作爲底層實現,所以它會很快。而且,如果您擔心這種情況的表現,那麼您可能根本不應該使用Python並查看其他技術。

即使幻想解決方案 - 使用ZeroC ICE。這是非常現代的技術,允許幾乎無縫的進程間通信。這是一個CORBA殺手,非常容易使用。它被許多人大量使用,被證明是同類中最快和穩定的搖滾。這種解決方案的優點在於,您可以將程序無縫集成到許多不同的語言中,如Python,Java,C++等。但這需要您花一些時間來熟悉一個概念。如果你決定這樣做,只需花一天時間閱讀低谷文檔。

希望它有幫助。祝你好運!

+0

謝謝你的回答詳細。 gevent processes.py示例的問題是,它僅實現一個通信步驟。我們正在使用一個可隨時發送數據的工作人員,同時我們可以向其發送命令,如停止命令。但它不會終止子進程,它應該保持可用。但是,我會嘗試整合兩個循環。它可能無法幫助Windows,但值得一試。使用TCP/IP是我正在考慮的另一種選擇,但它需要一個包裝層,這使事情變得複雜,並使解決方案變得非常重要。我會看看ZeroC ICE。 – fviktor 2011-02-25 10:02:29

0

你的問題已經很老了。不過,我想推薦http://gehrcke.de/gipc,我相信它會以非常直接的方式解決概述性的挑戰。基本上,它允許您在應用程序中的任何位置(也在Windows上)集成基於多處理的子進程。與Process對象(如調用join())的互動是gevent-cooperative。通過管道管理,它可以協同阻止進程間通信。但是,在Windows上,IPC當前效率低於POSIX兼容系統(因爲非阻塞I/O是通過線程池模仿的)。根據應用程序的IPC消息傳遞量,這可能或可能不重要。