2016-02-12 45 views
1

我想在seperte進程中啓動ActorCore方法,然後處理髮送到該ActorCore的消息。出於某種原因,此代碼無法正常工作。Python:如何在單獨的進程中調用方法

import queue 
from multiprocessing import Process 


class NotMessage(Exception): 
    def __str__(self): 
     return 'NotMessage exception' 


class Message(object): 

    def Do(self, Actor): 
     # Do some stuff to the actor 
     pass 

    def __str__(self): 
     return 'Generic message' 


class StopMessage(Message): 

    def Do(self, Actor): 
     Actor.__stopped = True 

    def __str__(self): 
     return 'Stop message' 


class Actor(object): 
    __DebugName = '' 
    __MsgQ = None 
    __stopped = False 

    def __init__(self, Name): 
     self.__DebugName = Name 
     self.__MsgQ = queue.Queue() 

    def LaunchActor(self): 
     p = Process(target=self.ActorCore) 
     p.start() 
     return self.__MsgQ 

    def ActorCore(self): 
     while not self.__stopped: 
      Msg = self.__MsgQ.get(block=True) 
      try: 
       Msg.Do(self) 
       print(Msg) 
      except NotMessage as e: 
       print(str(e), ' occurred in ', self.__DebugName) 


def main(): 
    joe = Actor('Joe') 
    msg = Message() 
    stop = StopMessage() 
    qToJoe = joe.LaunchActor() 
    qToJoe.put(msg) 
    qToJoe.put(msg) 
    qToJoe.put(stop) 

if __name__ == '__main__': 
    main() 

運行時,我得到奇怪的錯誤:

Traceback (most recent call last): 
    File "C:/Users/plkruczp/PycharmProjects/ActorFramework/Actor/Actor.py", line 64, in <module> 
    main() 
    File "C:/Users/plkruczp/PycharmProjects/ActorFramework/Actor/Actor.py", line 58, in main 
    qToJoe = joe.LaunchActor() 
    File "C:/Users/plkruczp/PycharmProjects/ActorFramework/Actor/Actor.py", line 40, in LaunchActor 
    p.start() 
    File "C:\Program Files\Python35\lib\multiprocessing\process.py", line 105, in start 
    self._popen = self._Popen(self) 
    File "C:\Program Files\Python35\lib\multiprocessing\context.py", line 212, in _Popen 
    return _default_context.get_context().Process._Popen(process_obj) 
    File "C:\Program Files\Python35\lib\multiprocessing\context.py", line 313, in _Popen 
    return Popen(process_obj) 
    File "C:\Program Files\Python35\lib\multiprocessing\popen_spawn_win32.py", line 66, in __init__ 
    reduction.dump(process_obj, to_child) 
    File "C:\Program Files\Python35\lib\multiprocessing\reduction.py", line 59, in dump 
    ForkingPickler(file, protocol).dump(obj) 
TypeError: can't pickle _thread.lock objects 

請幫助!我什麼都試過:(

回答

1

只需使用隊列,而不是隊列:

刪除import queue並添加Queuefrom multiprocessing像:

from multiprocessing import Process,Queue

然後更改self.__MsgQ = queue.Queue()self.__MsgQ = Queue()

這就是你需要做才能讓它起作用,其餘的對於你的情況是一樣的。

編輯,解釋:

queue.Queue僅僅是線程安全的,並且multiprocessing不實際產生另一個進程。因此,額外的multiprocessing.Queue被實現爲也是過程安全的。作爲另一種選擇,如果多線程被通緝,該threading庫可以一起queue.Queue使用:https://docs.python.org/dev/library/threading.html#module-threading

其他信息:

另一個並行選項,根據您的特殊要求是joblib,在那裏產卵可定義爲一個進程或線程:https://pythonhosted.org/joblib/

+0

謝謝,它的工作原理。這裏有什麼問題?是否隊列不是線程安全的,但隊列是? – Kruczkowski

+0

queue.Queue只有線程安全,而multiprocessing.Queue既是線程安全的,也是過程安全的。不要混淆線程和進程。對於線程,你需要「線程化」而不是「multiprocessing」(抱歉多次編輯,我在第二次之前出錯了) – bluesceada

相關問題