多处理基础

2024-04-27 04:52:40 发布

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

考虑到广泛的搜索,我仍然很难使用多个进程运行特定的函数。要求如下:

  • 限制进程数
  • 传递多个参数到映射

然而,最新的尝试正在进行时间。睡眠似乎影响了所有进程-执行时间相同-20秒,不管池是用于直接调用多进程foo还是foo(应该分别为4/20秒)。我错过了什么?你知道吗

from multiprocessing import Pool, Process, Lock
import os
import time

def foo(arg):
    print '{} - {}'.format(arg[0], os.getpid())
    time.sleep(1)

if __name__ == '__main__':
    script_start_time = time.time()

    pool = Pool(processes=5)
    for i in range(20):
        arg = [i, i]
        pool.map(foo, [arg])

    pool.close() #necessary to prevent zombies
    pool.join() #wait for all processes to finish

    print 'Execution time {}s '.format(time.time() - script_start_time)

结果:

0 - 5660
1 - 5672
2 - 5684
3 - 5704
4 - 5716
5 - 5660
6 - 5672
7 - 5684
8 - 5704
9 - 5716
10 - 5660
11 - 5672
12 - 5684
13 - 5704
14 - 5716
15 - 5660
16 - 5672
17 - 5684
18 - 5704
19 - 5716
Execution time 20.4240000248s

Tags: importformatforfootime进程os时间
1条回答
网友
1楼 · 发布于 2024-04-27 04:52:40

正如在注释中提到的,pool.map将阻塞直到执行完成,因此您必须使用apply_asyncmap_async提交作业,并使用回调来处理返回数据的函数。或者,您可以提前构建所有输入,并一次对所有输入调用map。你知道吗

在本例中,apply\u async和map\u async非常相似,区别在于apply\u async一次只能提交一个作业,并且支持传递多个arg和kwarg。示例:

from multiprocessing import Pool
import os
import time

def add(a, b):
    c = a+b
    print(f'{a}+{b} = {c} from process: {os.getpid()}') #python 3 f-strings are nifty :)
    time.sleep(1)
    return c

if __name__ == '__main__':
    script_start_time = time.time()
    pool = Pool(processes=5)
    results = []
    for a in range(5):
        for b in range(5,10):
            pool.apply_async(add, (a,b), callback=lambda c: results.append(c))
    pool.close() #necessary to prevent zombies
    pool.join() #wait for all processes to finish
    print('results', results)
    print('Execution time {}s '.format(time.time() - script_start_time))

注意调用apply_async时参数是如何传递的。你知道吗

或者,可以使用普通映射一次传递所有参数,但是这要求函数只接受一个参数。这就是starmap方法有用的地方。它接受一个元组的iterable,并将元组解压到函数参数中,因此pool.starmap(foo, [(a,b),(c,d),(e,f)]的输入将把每对元组解压到foo中,foo包含两个参数:

if __name__ == '__main__':
    script_start_time = time.time()
    pool = Pool(processes=5)
    args = [(a,b) for a in "abc" for b in "ABC"]
    print(pool.starmap(add, args)) #same add function from before (works with strings too)
    pool.close() #necessary to prevent zombies
    pool.join() #wait for all processes to finish
    print('Execution time {}s '.format(time.time() - script_start_time))

相关问题 更多 >