gpt4 book ai didi

python - 多处理忽略 "__setstate__"

转载 作者:太空宇宙 更新时间:2023-11-04 08:04:37 24 4
gpt4 key购买 nike

我假设 multiprocessing 包使用 pickle 在进程之间发送东西。但是,pickle 会注意对象的 __getstate____setstate__ 方法。多处理似乎忽略了它们。它是否正确?我糊涂了吗?

要复制,安装 docker,然后输入命令行

$ docker run python:3.4 python -c "import pickle
import multiprocessing
import os

class Tricky:
def __init__(self,x):
self.data=x

def __setstate__(self,d):
self.data=10

def __getstate__(self):
return {}

def report(ar,q):
print('running report in pid %d, hailing from %d'%(os.getpid(),os.getppid()))
q.put(ar.data)

print('module loaded in pid %d, hailing from pid %d'%(os.getpid(),os.getppid()))
if __name__ == '__main__':
print('hello from pid %d'%os.getpid())
ar = Tricky(5)
q = multiprocessing.Queue()
p = multiprocessing.Process(target=report, args=(ar, q))
p.start()
p.join()
print(q.get())
print(pickle.loads(pickle.dumps(ar)).data)"

你应该得到类似的东西

module loaded in pid 1, hailing from pid 0
hello from pid 1
running report in pid 5, hailing from 1
5
10

我本以为应该是“10”“10”,但实际上是“5”“10”。这意味着什么?

(注意:根据 user3667217 的建议编辑代码以符合编程指南)

最佳答案

多处理模块可以通过以下三种方式之一启动:spawn、fork 或 forkserver。默认情况下,在 unix 上,它会 fork 。这意味着在新进程诞生时不需要 pickle 任何已经加载到 ram 中的东西。

如果您需要更直接地控制 fork 的发生方式,您需要将启动设置更改为 spawn。为此,创建一个上下文

ctx=multiprocessing.get_context('spawn')

并将所有对 multiprocessing.foo() 的调用替换为对 ctx.foo() 的调用。当你这样做时,每个新进程都会作为一个新的 python 实例诞生;发送到其中的所有内容都将通过 pickle 发送,而不是直接 memcopy。

关于python - 多处理忽略 "__setstate__",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33685329/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com