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

2024-04-25 11:48:06 发布

您现在位置:Python中文网/ 问答频道 /正文

我对多重处理还是个新手,但在过去的几天里我读了很多书,想看看我的想法是否适合使用多重处理。你知道吗

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

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对象,您可以通过Result.get()获得该对象的值,但在我描述的这种设置中,这似乎没有什么用处。你知道吗

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


Tags: nameinself示例forifdefjobs
1条回答
网友
1楼 · 发布于 2024-04-25 11:48:06

一般来说,不需要从传递给Pool.appy_async()的函数返回某些内容,但在本例中,有必要更新jobs列表中只存在于主进程中的相应Worker对象。你知道吗

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

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

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)

相关问题 更多 >