gpt4 book ai didi

python - 了解简单的多处理脚本

转载 作者:行者123 更新时间:2023-12-01 04:03:23 26 4
gpt4 key购买 nike

我试图了解 Python 的多处理模块是如何工作的。为此,我制作了我正在编写的代码的一个非常简单的版本,并尝试使其并行工作。根据我读到的内容,使用 pool比使用 mp.Process 更适合我的程序。

以下是我的想法:

import time, os
import multiprocessing as mp

class Foo:
def __init__(self, ID):
self.ID = ID

def showID(self):
for k in range(0,4):
print('Foo #', self.ID, '\tID:', os.getpid(), '\tParent ID:', os.getppid())
time.sleep(0.2)

# MAIN
if __name__ == '__main__':

print('parent process:', os.getppid())
print('process id:', os.getpid())
print(' ')

foos = [Foo(2), Foo(3)]

pool = mp.Pool(processes=2)

# Code below doesn't work
pool.apply_async(foos[0].showID, ())
pool.apply_async(foos[1].showID, ())

列表foos最终将包含 10 到 20 个对象。方法Foo.showID最终也会返回一些东西。我的目标是在需要运行任务时发送尽可能多的任务(foos成员),以便可以将它们分派(dispatch)到pool成员之一的流程。

如果我运行上面的代码,什么也不会发生,即。仅parent processprocess id显示在开头。如果我将最后两行替换为:

pool.apply_async(foos[0].showID())
pool.apply_async(foos[1].showID())

两者都在主进程中依次执行:

parent process: 3380
process id: 6556

Foo # 2 ID: 6556 Parent ID: 3380
Foo # 2 ID: 6556 Parent ID: 3380
Foo # 2 ID: 6556 Parent ID: 3380
Foo # 2 ID: 6556 Parent ID: 3380
Foo # 3 ID: 6556 Parent ID: 3380
Foo # 3 ID: 6556 Parent ID: 3380
Foo # 3 ID: 6556 Parent ID: 3380
Foo # 3 ID: 6556 Parent ID: 3380

最后,如果我用这样的东西替换它们:

pool.apply_async(foos[0].showID, ())
pool.apply_async(foos[1].showID())

我得到了预期的行为(我认为):

parent process: 3380
process id: 4772

Foo # 3 ID: 4772 Parent ID: 3380
Foo # 2 ID: 6364 Parent ID: 4772
Foo # 3 ID: 4772 Parent ID: 3380
Foo # 2 ID: 6364 Parent ID: 4772
Foo # 3 ID: 4772 Parent ID: 3380
Foo # 2 ID: 6364 Parent ID: 4772
Foo # 3 ID: 4772 Parent ID: 3380
Foo # 2 ID: 6364 Parent ID: 4772

这里发生了什么?如果我尝试使用 Foo 中未定义的函数,我会注意到相同的行为类。

最佳答案

apply_async接收一个函数

当您使用不带括号的 foos[0].showID 时,您将传递该函数,而不是调用它,而是在执行时

pool.apply_async(foos[0].showID())

您首先评估 foos[0].showID(),然后将其返回值作为参数传递给 apply_async。最终执行评估的是 apply_async 的调用者,这就是同步处理。

这相当于做:

foos[0].showID()
pool.apply_async()
foos[1].showID()
pool.apply_async()

您的第一次尝试失败,因为您没有等待异步调用执行。调用后。

pool.apply_async(foos[0].showID, ())
pool.apply_async(foos[1].showID, ())

您的程序退出,因此您无需等待输出。

终于

pool.apply_async(foos[0].showID, ())
pool.apply_async(foos[1].showID())

相当于:

pool.apply_async(foos[0].showID, ())
foos[1].showID()

进行一次异步调用和一次同步调用,因此它可以工作。

关于python - 了解简单的多处理脚本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36117544/

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