Python 如何在Multiprocessing Pool.map中正确引用类的实例?

Python 如何在Multiprocessing Pool.map中正确引用类的实例?,python,python-3.x,python-multiprocessing,Python,Python 3.x,Python Multiprocessing,假设我定义了以下类: class Animal: def __init__(self): self.isAlive = True 与以下功能一起: def Kill_Animal(animal): animal.isAlive = False 现在,如果我创建一个动物列表,如下所示: AnimalsList = [Animal() for i in range(0,5)] [print(animal.isAlive) for animal in Animal

假设我定义了以下类:

class Animal:
    def __init__(self):
        self.isAlive = True
与以下功能一起:

def Kill_Animal(animal):
    animal.isAlive = False
现在,如果我创建一个动物列表,如下所示:

AnimalsList = [Animal() for i in range(0,5)]
[print(animal.isAlive) for animal in AnimalsList]
如果该函数应用于列表中Animal类的任何实例,isAlive属性将更改为False。但是,如果我想将此函数应用于此列表并通过多处理库更改其内容,那么正确的方法是什么

我尝试了以下方法:

from multiprocessing import Process, Pool

pool = Pool()
pool.map(Kill_Animal, AnimalsList[0:3])
但是,如果我尝试检查列表中所有元素的属性,结果如下:

AnimalsList = [Animal() for i in range(0,5)]
[print(animal.isAlive) for animal in AnimalsList]
输出:真

此外,如果我尝试在运行时通过Pool.Map检查传递给Kill_Animal函数的对象ID,它与对象自己的ID不匹配。我熟悉Python的对象引用调用,但这里发生了什么

在研究了这个概念之后,我理解了对这个概念的误解

使用多处理,即使类的实例作为参数传递,ID与调用方法中的ID不同也是有意义的,因为现在我们使用的是不同的进程,因此该对象是原始对象的副本,与内存中的相同位置不对应。因此,在副本中所做的任何更改都不会影响其原始实例

为了使用并行性和共享状态,必须应用不同的概念,如中提供的多线程。这里已经详细讨论了多线程和多处理之间的区别:

回到原来的问题,可以通过两种简单的方法循环列表并应用函数:

def Kill_Animal(animal):
    animal.isAlive = False
1.使用: multiprocessing.dummy复制了多处理的API,但只不过是线程模块的包装器

因此,答案可以写为:

import multiprocessing.dummy as mp
p = mp.Pool(3) # With 3 being the number of threads.
p.map(Kill_Animal, AnimalsList)
p.close()
p.join()

[print(animal.isAlive) for animal in AnimalsList]
输出:False False

2.使用:
输出:False

多处理
不共享状态。它实际上是多个不同的python进程。@juanpa.arrivillaga我明白了。那么,如果我想用多处理修改一个类的实例(而不是替换它),那么正确的方法是什么呢?理想的方法是重构代码,使其不需要共享状态。我会通读全文,看看你有什么选择来分享这个州。@juanpa.arrivillaga谢谢。是的,我有一个类,其中包含大量用于selenium web解析的模块,并且串行执行非常有效。我一直试图通过同时运行多个浏览器来增加并行性以提高性能,但也许我从错误的角度来看待它。您可以使用多种方法(包括多处理的队列和管理器)跨进程共享状态,但就Selenium而言,您可能希望将作业详细信息发送到流程,并让它们独立地实例化自己的资源,而不是像这样尝试传递对象。当然,要小心这一点,因为太多的无头浏览器很容易引起OOM杀手的愤怒。