gpt4 book ai didi

python - 更新来自不同进程的相同实例变量

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

这是一个简单的 secinaro:

class Test:
def __init__(self):
self.foo = []

def append(self, x):
self.foo.append(x)

def get(self):
return self.foo

def process_append_queue(append_queue, bar):
while True:
x = append_queue.get()
if x is None:
break
bar.append(x)
print("worker done")

def main():
import multiprocessing as mp
bar = Test()
append_queue = mp.Queue(10)
append_queue_process = mp.Process(target=process_append_queue, args=(append_queue, bar))
append_queue_process.start()

for i in range(100):
append_queue.put(i)
append_queue.put(None)
append_queue_process.join()

print str(bar.get())

if __name__=="__main__":
main()

当您在 main() 函数末尾调用 bar.get() 时,为什么它仍然返回一个空列表?我怎样才能使子进程也使用 Test 的相同实例而不是新实例?

感谢所有答案!

最佳答案

通常,进程具有不同的地址空间,因此一个进程中的对象的突变不会影响任何其他进程中的任何对象。需要进程间通信来告知一个进程在另一个进程中所做的更改。

这可以明确地完成(使用诸如 multiprocessing.Queue 之类的东西),或者如果您为此目的使用由 multiprocessing 实现的设施,则可以隐式地完成。例如,大量工作是在幕后完成的,以对跨进程可见的 multiprocessing.Queue 进行更改。

在您的特定示例中,最简单的方法是像这样替换您的 __init__ 函数:

def __init__(self):
import multiprocessing as mp
self.foo = mp.Manager().list()

碰巧一个 mp.Manager 实例支持一个 list() 方法,它创建一个进程感知列表对象(实际上是一个列表对象的代理,它将列表操作转发到一个隐藏的服务器进程,该进程维护“真实”列表的单个副本 - 列表对象并没有真正跨进程共享,因为那是不可能的 - 但代理使它出现 共享)。

因此,如果您进行更改,您的代码将显示您期望的结果 - 没有比这更简单的方法了。

请注意,您需要的 IPC(进程间通信)越少,多处理效果越好,无论应用程序或编程语言如何,这几乎都是事实。

关于python - 更新来自不同进程的相同实例变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37246146/

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