我试图了解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
成员),以便可以将它们分派到pool
的进程之一。如果我运行上面的代码,则什么也不会发生。仅显示开头的
parent process
和process 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/