【问题标题】:Python: How to call method in separate processPython:如何在单独的进程中调用方法
【发布时间】:2016-02-12 10:12:35
【问题描述】:

我想在一个单独的进程中启动 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

请帮忙!我什么都试过了:(

【问题讨论】:

    标签: python class methods process


    【解决方案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://joblib.readthedocs.io/

    【讨论】:

    • 谢谢,它有效。这里出了什么问题?是不是队列不是线程安全的,但队列是线程安全的?
    • queue.Queue 仅是线程安全的,而 multiprocessing.Queue 既是线程安全的又是进程安全的。不要混淆线程和进程。对于您需要threading 而不是multiprocessing 的线程(抱歉多次编辑,我一秒钟前这里出了点问题)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-30
    • 1970-01-01
    • 1970-01-01
    • 2015-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多