Python 使用void方法/setter方法进行多处理

Python 使用void方法/setter方法进行多处理,python,multiprocessing,Python,Multiprocessing,我对多重处理还是个新手,但在过去几天里,我读了很多书,想看看我的想法是不是可以用多重处理 许多联机多处理示例如下所示: def worker(): print('Worker') if __name__ == '__main__': jobs = [] for i in range(5): p = multiprocessing.Process(target=worker) jobs.append(p) p.start(

我对多重处理还是个新手,但在过去几天里,我读了很多书,想看看我的想法是不是可以用多重处理

许多联机多处理示例如下所示:

def worker():
    print('Worker')

if __name__ == '__main__':
    jobs = []

    for i in range(5):
        p = multiprocessing.Process(target=worker)
        jobs.append(p)
        p.start()
但是多处理的示例方法总是返回或打印一些东西!有没有一种方法我可以做到以下几点

import multiprocessing

class Worker():
    def __init__(self):
        self.level=0
    def setLevel(self,val):
        self.level=val

def method(worker, level):
     worker.setLevel(level)

if __name__ == '__main__':
    jobs = []
    for i in range(5):
        jobs.append(Worker())
    pool=multiprocessing.Pool()
    for i in range(5):
       worker=jobs[i]
       res = pool.apply_async(method, args=(worker,i,))
    pool.close()
    pool.join()
    for worker in jobs:
        print(worker.level)
我知道
apply\u async
返回一个result对象,您可以通过
result.get()
获得该对象的值,但在我描述的这种设置中,这似乎没有什么用处


当我执行下面的代码时,我得到的是
0 0 0
而不是所需的
0 1 2 3 4
结果。

一般来说,不需要从传递到
Pool.appy_async()
的函数返回某些内容,但是在这种情况下,有必要更新
作业
列表中仅存在于主进程中的相应
工作者
对象

这是因为当进行多处理时,每个进程都在自己的内存空间中运行,这意味着您不能在它们之间共享全局变量。有很多方法可以模拟这种情况,但这通常会带来很多开销,而且实际上可能会使多处理带来的任何收益付诸东流。每个子进程都会获得一个
Worker
对象的副本

考虑到这一点,这里有一种让代码正常工作的方法。
method()
函数现在将更新后的
Worker
对象的(副本)返回主进程,主进程将与每个对象关联的所有结果对象存储在名为
results
的单独列表中。在
pool.join()
调用之后处理完所有作业后,该列表将用于替换最初放入
作业
列表中的每个
工作者
对象-仅使其显示为它们自己已更新

import multiprocessing


class Worker():
    def __init__(self):
        self.level = 0

    def setLevel(self,val):
        self.level = val


def method(worker, level):
    worker.setLevel(level)
    return worker  # ADDED - return updated Worker object.


if __name__ == '__main__':
    jobs = []
    for i in range(5):
        jobs.append(Worker())

    results = []
    pool = multiprocessing.Pool()
    for i in range(5):
        worker = jobs[i]
        results.append(pool.apply_async(method, (worker, i)))

    pool.close()
    pool.join()

    # Update Workers in jobs list.
    for i, result in enumerate(results):
        jobs[i] = result.get()  # Replace workers with their updated version.

    for worker in jobs:
        print(worker.level)

非常感谢。您必须以这种方式重写代码,这是非常令人失望的,但至少我现在有了一个答案Anthony:根据worker函数的实际情况,多线程可能是一种更好的方法,因为在使用它时可以共享全局对象和数据(如果您做得正确的话)。但是,如果worker进行大量计算,那么这并不是最佳选择(不同于这个小例子中所做的)。我正在学习多处理以加速我编写的算法,该算法使用lxml库将XML文件解析到树中,然后(通过多处理)从自顶向下的方法标记其元素节点(先从孩子最多的父母开始,然后慢慢来)。我认为我的算法确实需要大量计算,因为它在大文件上使用整个处理器(12.5%),速度非常慢。我曾尝试过ThreadPoolExecutor,但我不确定我是否做得正确(尝试时没有工作)Anthony:在Python中,线程最适合于I/O绑定的任务,因为它允许其他任务在其他任务等待I/O完成时运行。在使用它时,您必须小心控制对共享资源(如全局变量)的并发访问。多处理可以帮助加快计算绑定的任务,但需要收集中间数据生成最终结果可能会再次减慢速度。进行并行处理的挑战通常是设计一种方法来完成需要完成的工作,以避免或至少最小化共享数据的需要—使任务独立。