Python 创建一个可以跨流程进行比较的变量

Python 创建一个可以跨流程进行比较的变量,python,process,python-3.x,multiprocessing,Python,Process,Python 3.x,Multiprocessing,我有如下代码 class _Process(multiprocessing.Process): STOP = multiprocessing.Manager().Event() def __init__(self, queue, process_fn): self._q = queue self._p = process_fn super().__init__() def run(self): wh

我有如下代码

class _Process(multiprocessing.Process):

    STOP = multiprocessing.Manager().Event()

    def __init__(self, queue, process_fn):

        self._q = queue
        self._p = process_fn
        super().__init__()

    def run(self):

        while True:
            dat = self._q.get()
            if not dat is _Process.STOP:
                self._p(dat, self._q)
                self._q.task_done()
            else:
                self._q.task_done()
                break
但是,我无法成功比较
STOP
。当我使用
is
时,这并不奇怪,因为我相信,
is
比较对象id和文档中的“…这是内存中对象的地址”。因此,由于我使用多个进程,内存地址将不同。(不过,我也无法将其与
==
进行比较,我也不确定这是为什么)

这发生在我使用
Manager()
创建的任何对象上,但如果我使用“true”单例(
true
False
None
),它确实有效。尽管这不是一个合适的解决方案,因为这些值中的任何一个都可能在队列中有效

那么,我如何创建一个变量,比如单例变量,可以跨流程进行比较呢

(注意,我也尝试过使用一个专用类,但由于无法对其进行pickle处理而出现错误。)

更新:答案似乎是使用一个类,但我收到了一些问题,因为我只是尝试使用一个内部类。将其移动到模块范围修复了错误,工作正常。-谢谢@Schnouki


下面是代码的一个示例(也是毫无意义的)用法,它显示了错误

def f(data, queue):
    print(data)

q = multiprocessing.JoinableQueue()

for i in range(4):
    p = _Process(q, f)
    p.daemon = True
    p.start()
    q.put(i)

q.join()

for i in range(4):
    q.put(_Process.STOP)

q.join()

这是一种使用
事件
对象的奇怪方式。。。如果您不能使用
None
或布尔值,我建议您使用专用类并测试从队列中获得的内容的类型:

class StopProcessing(object):
    pass

#...

q.put(StopProcessing())

#...

while True:
    dat = self._q.get()
    if type(dat) is StopProcessing:
        # ...
当然,您也可以继续使用
multiprocessing.Event
并测试其类型。然而,对于阅读您的代码的其他人来说,这可能是相当误导的;对我来说,使用专用类型似乎更干净、更具吸引力

编辑:好,显然这不起作用,因为新类不可拾取。所以这里有另一个想法:如果您直接将类型放入队列中,会怎么样

class StopProcessing(object):
    pass
#...
q.put(StopProcessing)
#...
while True:
    dat = self._q.get()
    if dat is StopProcessing:
        #...

根据说明,“在模块顶层定义的类”可以被pickle。

谢谢,我刚才使用了
Event
作为示例。就像我说的那样,
Manager
返回的任何对象都会发生这种情况,我可能会在一天结束时使用
Value
,如果它起作用的话(不确定为什么我在示例中没有这么做!)。谢谢你给我的关于使用类的建议,我应该提到,我已经尝试过了,并且得到了一个关于类不能被腌制的错误。我已经更新了问题以提及这一点。如果您直接将类型放入队列中,例如
q.put(StopProcessing)
,然后使用
测试dat是否正在停止处理
?根据这篇文章,“在模块的顶层定义的类”可以被pickle。啊!我试过只添加类型,是的。事实上,在处理
Manager
对象之前,这是我尝试的第一件事,但我总是将类作为一个内部类。将其纳入模块范围可以使其完美工作。非常感谢。我想知道你是否可以在你的答案中添加这个提示,以匹配我在问题中的更新。