通过void方法/ setter方法使用多重处理

时间:2019-07-09 17:43:40

标签: 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()

但是用于多处理的示例方法总是返回或打印某些内容!有什么方法可以执行以下操作?

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_async返回一个结果对象,您可以使用Result.get()获得该对象的值,但是在像我描述的那样的设置中这似乎没有用。

执行以下代码时,我得到0 0 0 0 0而不是期望的0 1 2 3 4结果。

1 个答案:

答案 0 :(得分:1)

通常来说,不需要从传递给Pool.appy_async()的函数中返回某些内容,但是在这种情况下,有必要更新Worker列表中对应的jobs对象,仅存在于主要过程中。

这是因为当multiprocessing时,每个进程都在其自己的内存空间中运行,这意味着您无法在它们之间共享全局变量。有一些方法可以模拟这种情况,但通常会产生大量开销,并且实际上可能会抵消执行多处理的任何收益。每个子流程都经过Worker对象的副本

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

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)