python之pool.apply_async

源于: 执行类代码 --parallel_str_search.py – 函数do_search


进程池pool中的apply方法与apply_async方法比较:

1. apply方法是阻塞的
   意思是等待当前子进程执行完毕后,再执行下一个进程。

import time
from multiprocessing import Pool
def run(msg):
    print('msg:%s' %msg)
    # 程序随眠3秒,
    time.sleep(3)
    print('end')
if __name__ == "__main__":
    print("开始执行主程序")
    start_time=time.time()
    # 使用进程池创建子进程
    size=3
    pool=Pool(size)
    print("开始执行子进程")
    for i in range(size):
        pool.apply(run,(i,))
    print("主进程结束耗时%s"%(time.time()-start_time))

结果为:

开始执行主程序
开始执行子进程
msg:0
end
msg:1
end
msg:2
end
主进程结束耗时9.223527431488037

2. apply_async是异步非阻塞的
   意思是不用等待当前进程执行完毕,随时根据系统调度来进行进程切换

applay达不到多进程效果,而apply_async属于异步,主进程和子进程同时跑,谁跑的快,谁先来。

import time
from multiprocessing import Pool
def run(msg):
    print('msg:%s' %msg)
    # 程序随眠3秒,
    time.sleep(3)
    print('end')
if __name__ == "__main__":
    print("开始执行主程序")
    start_time=time.time()
    # 使用进程池创建子进程
    size=3
    pool=Pool(size)
    print("开始执行子进程")
    for i in range(size):
        pool.apply_async(run,(i,))
    print("主进程结束耗时%s"%(time.time()-start_time))

结果为:

开始执行主程序
开始执行子进程
主进程结束耗时0.06100344657897949

1. 为何时间上的差距如此之大?

   因为进程的切换是操作系统来控制的,抢占式的切换模式。 我们首先运行的是主进程,cpu运行很快啊,这短短的几行代码,完全没有给操作系统进程切换的机会,主进程就运行完毕了,整个程序结束。子进程完全没有机会切换到程序就已经结束了。

2. 阻塞式的apply

  首先主进程开始运行,碰到子进程,操作系统切换到子进程,等待子进程运行结束后,再切换到另外一个子进程,直到所有子进程运行完毕。然后在切换到主进程,运行剩余的部分。

3. 异步非阻塞式的apply_async

  首先主进程开始运行,碰到子进程后,主进程说:让我先运行个够,等到操作系统进行进程切换的时候,再交给子进程运行。因为我们的程序太短,还没等到操作系统进行进程切换,主进程就运行完毕了。

python官方建议:废弃apply,使用apply_async


pool.apply_async的用法:

import multiprocessing
import multiprocessing
import time
import random
import sys

# print 'Testing callback:'
def mul(a, b):
    time.sleep(0.5*random.random())
    return a * b

def pow3(x):
    return x ** 3

if __name__ == '__main__':
    multiprocessing.freeze_support() # 在Windows下编译需要加这行

    PROCESSES = 4
    print('Creating pool with %d processes\n' % PROCESSES)
    pool = multiprocessing.Pool(PROCESSES)

    A = []
    B = [56, 0, 1, 8, 27, 64, 125, 216, 343, 512, 729]

    r = pool.apply_async(mul, (7, 8), callback=A.append)
    r.wait()
    
    print(A)
    print(B)


    r = pool.map_async(pow3, range(10), callback=A.extend)
    r.wait()
    
    print(A)
    print(B)

    if A == B:
        print('\tcallbacks succeeded\n')
    else:
        print('\t*** callbacks failed\n\t\t%s != %s\n' % (A, B))

结果为:

Creating pool with 4 processes

[56]
[56, 0, 1, 8, 27, 64, 125, 216, 343, 512, 729]
[56, 0, 1, 8, 27, 64, 125, 216, 343, 512, 729]
[56, 0, 1, 8, 27, 64, 125, 216, 343, 512, 729]
	callbacks succeeded
发布了255 篇原创文章 · 获赞 28 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/weixin_43283397/article/details/104294890
今日推荐