2015-08-22 44 views
1

我遇到了以下問題:Python多處理 - 兩個進程之間的函數式通信

我有兩個不同的類;我們稱他們爲interfaceworker。該接口應該接受來自外部的請求,並將它們複用到多個工作人員。

相反,我發現幾乎每一個例子,我有幾個特點:

  • 工人不應該被重建爲每個請求。
  • 工人是不同的;請求workers[0]無法通過workers[1]回答。該複用在interface中完成。
  • 我有一些類似函數的調用很難通過事件或簡單的隊列進行建模。
  • 有幾個不同的請求,這將使每個請求的一個隊列變得困難。

例如,假設每個工作人員正在存儲一個整數(假設這個工作人員收到的調用次數)。在非並行處理,我會使用這樣的:

class interface(object): 
    workers = None #set somewhere else. 

    def get_worker_calls(self, worker_id): 
     return self.workers[worker_id].get_calls() 

class worker(object) 
    calls = 0 

    def get_calls(self): 
     self.calls += 1 
     return self.calls 

 

顯然,這是行不通的。什麼?

或者,也許更相關的是,我沒有多處理經驗。有沒有我很想念的設計範例,可以輕鬆解決上述問題?

謝謝!

 

 

僅供參考,我也考慮過幾種方法,而我無法找到一個很好的一個:

  • 使用一個請求和回答隊列。我放棄了這個想法,因爲它會阻止interface'爲當前工作人員的回答時間(使其可擴展性極差),或者需要我發送額外的信息。
  • 使用一個請求隊列。每條消息都包含一個管道以返回該請求的答案。修復issue with being unable to send pipes via pipes後,我遇到了管道關閉的問題,除非通過連接發送兩端。
  • 使用一個請求隊列。每條消息都包含一個隊列以返回該請求的答案。由於無法通過隊列發送隊列,因此失敗,但減少技巧不起作用。
  • 以上內容也適用於相應的管理器生成的對象。

回答

0

多處理意味着你有2+分離的進程運行。沒有辦法直接從一個進程訪問內存(如同多線程一樣)。

你最好的辦法是使用某種外部隊列機制,你可以從CeleryRQ開始。 RQ更簡單,但芹菜具有內置監控功能。

但是你必須知道,只有當Celery/RQ能夠「包裝」所需的功能/類並將它們發送到其他進程時,多處理才能工作。因此,您必須使用__main__級別的函數(位於文件頂部,不屬於任何類)。

你可以自己實現它,Redis很簡單,ZeroMQ和RabbitMQ也不錯。

Beaver library是如何處理Python中使用ZeroMQ隊列的多處理的好例子。