多重处理可在Ubuntu中运行,而不适用于Windows

多重处理可在Ubuntu中运行,而不适用于Windows,第1张

多重处理可在Ubuntu中运行,而不适用于Windows

问题在于

MyBus
对象的某些部分不可腌制,并且您正在将实例保存
MyBus
Broker
实例中。由于Windows缺乏
fork()
支持,因此在调用时
broker.start()
broker
必须在
multiprocessing
产生的子进程中对的整个状态进行酸洗并重新创建
broker.run
。它可以在Linux上运行,因为Linux支持
fork
。在这种情况下,它不需要腌制任何东西-
子进程在分叉后立即包含父级的完整状态。

解决此问题的方法有两种。第一种也是更困难的方法是使您的

broker
实例可腌制。为此,您需要将其变为可
MyBus
腌制的。您现在遇到的错误是指上的
logger
属性
MyBus
,该属性不可腌制。这个很容易解决;只需向中添加
__getstate__
/
__setstate__
方法
MyBus
,即可控制如何对对象进行酸洗/酸洗。如果我们在腌制时删除记录器,而在腌制时重新创建它,则可以解决此问题:

class MyBus(wspbus.Bus):    ...     def __getstate__(self):        self_dict = self.__dict__        del self_dict['logger']        return self_dict    def __setstate__(self, d):        self.__dict__.update(d)        self.open_logger()

这可行,但是然后我们遇到 另一个 酸洗错误:

Traceback (most recent call last):  File "async2.py", line 121, in <module>    broker.start()  File "C:python34libmultiprocessingprocess.py", line 105, in start    self._popen = self._Popen(self)  File "C:python34libmultiprocessingcontext.py", line 212, in _Popen    return _default_context.get_context().Process._Popen(process_obj)  File "C:python34libmultiprocessingcontext.py", line 313, in _Popen    return Popen(process_obj)  File "C:python34libmultiprocessingpopen_spawn_win32.py", line 66, in __init__    reduction.dump(process_obj, to_child)  File "C:python34libmultiprocessingreduction.py", line 60, in dump    ForkingPickler(file, protocol).dump(obj)_pickle.PicklingError: Can't pickle <class 'cherrypy.process.wspbus._StateEnum.State'>: attribute lookup State on cherrypy.process.wspbus failed

结果是

cherrypy.process.wspbus._StateEnum.State
,它是
wspbus.Bus
继承的类的属性
MyBus
,是一个嵌套类,不能对嵌套类进行腌制:

class _StateEnum(object):    class State(object):        name = None        def __repr__(self): return "states.%s" % self.name

State
对象(惊喜)用于跟踪
Bus
实例的状态。由于在启动总线之前要进行酸洗,所以我们可以在酸洗
state
时从对象中删除属性,然后在酸洗时将其设置为States.STOPPED。

class MyBus(wspbus.Bus):    def __init__(self, name=""):        wspbus.Bus.__init__(self)        self.open_logger(name)        self.subscribe("log", self._log)    def __getstate__(self):        self_dict = self.__dict__        del self_dict['logger']        del self_dict['state']        return self_dict    def __setstate__(self, d):        self.__dict__.update(d)        self.open_logger()        self.state = wspbus.states.STOPPED  # Initialize to STOPPED

通过这些更改,代码可以按预期工作!唯一的限制是,只有

MyBus
在总线尚未启动的情况下,才可以安全地进行腌制,这对于您的用例来说是很好的。

同样,这是困难的方法。最简单的方法是完全消除对

MyBus
实例进行酸洗的需要。您可以
MyBus
在子进程中创建实例,而不是在父进程中创建实例:

class Broker(Process):    def __init__(self, queue):        Process.__init__(self)        self.queue = queue...    def run(self):        self.bus = MyBus(Broker.__name__)  # Create the instance here, in the child        self.bus.subscribe("main", self.check)        self.bus.start()        self.bus.block(interval=0.01)

只要您不需要

broker.bus
在父级中访问,这就是更简单的选择。



欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/4937962.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-11-13
下一篇 2022-11-13

发表评论

登录后才能评论

评论列表(0条)

保存