Python:如何在单独的进程中调用方法

时间:2016-02-12 10:12:36

标签: python class methods process

我想在seperte进程中启动ActorCore方法,然后处理发送到该ActorCore的消息。由于某些原因,此代码无效。

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 个答案:

答案 0 :(得分:1)

只需使用队列而不是队列:

删除import queue并将Queue添加到from 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/