python_并发编程——进程池

1.进程池

from multiprocessing import Pool

def func(n):
    for i in range(10):
        print(n+1)

if __name__ == '__main__':
    pool = Pool(3)  #启动有三个进程的进程池。
    #第一个参数进程要访问的代码,第二个参数必须是一个可迭代参数,规定了要执行的任务数
    pool.map(func,range(100))   #100个任务

结果:  每个数打印了10次。

2.进程池和多进程的用时对比

def func(n):
    for i in range(10):
        print(n + 1)

if __name__ == '__main__':
    start = time.time()
    pool = Pool(3)  #启动有三个进程的进程池。
    #第一个参数进程要访问的代码,第二个参数必须是一个可迭代参数,规定了要执行的任务数
    pool.map(func,range(100))   #100个任务
    t1 = time.time() - start

    start = time.time()
    p_list = []
    for i in range(100):
        p = Process(target=func,args=(i,))
        p_list.append(p)
        p.start()
    for p in p_list:
        p.join()
    t2 = time.time() - start
    print(t1,t2)

结果:  进程池的用0.9,而多进程的用了17+

3.进程池的另一种实现方式

from multiprocessing import Pool
import time
import os

def func(n):
    print('start func{}'.format(n),os.getpid())
    time.sleep(1)
    print('end func{}'.format(n),os.getpid())

if __name__ == '__main__':
    p = Pool(5)
    for i in range(10):
        # (调用的方法,传递参数(以元组的形式传递参数))
        p.apply_async(func,args=(i,))
    p.close()   #结束进程池接收任务
    p.join()    #感知进程池中的任务执行结束

结果:  可以看到有任务执行完毕后,进程被新的任务利用。apply_async()方法如果想执行完,再继续执行主进程中的代码必须配合 close()方法和join()方法使用。

4.进程池的返回值

from multiprocessing import Pool
import time

def func(n):
    time.sleep(0.5)
    return n*n      #返回值

if __name__ == '__main__':
    p = Pool()
    for i in range(10):
        res = p.apply_async(func,args=(i,))     #将返回值放到res这个对象中
        print(res.get())    #get方法等待从res中获取值,但是会形成阻塞,只有get到数据时在会执行

结果:  每0.5秒打印一个值。失去了进程池的效果。

 解决:

from multiprocessing import Pool
import time

def func(n):
    time.sleep(0.5)
    return n*n      #返回值

if __name__ == '__main__':
    p = Pool()
    res_list = []   #创建一个存储进程返回值对象的列表
    for i in range(10):
        res = p.apply_async(func,args=(i,))     #将返回值放到res这个对象中
        res_list.append(res)    #将返回值对象存放到列表中
    for i in res_list:
        print(i.get())  

结果:  实现并发五个一组的打印子进程的返回值。

map方法接收进程池的返回值:

from multiprocessing import Pool
import time

def func(n):
    time.sleep(0.5)
    return n*n      #返回值

if __name__ == '__main__':
    p = Pool(5)
    ret = p.map(func,range(10))
    print(ret)

结果:,将进程池的全部返回值存放在列表中,然后一次性打印列表。

5.进程池的回调函数

from multiprocessing import Pool
import os

def func1(n):
    print('函数1',os.getpid())
    return n*n
def func2(nn):
    print('回调函数2',os.getpid())
    print(nn)
if __name__ == '__main__':
    print('主进程:',os.getpid())
    p = Pool(5)
    p.apply_async(func1,args=(10,),callback=func2)    #子进程要执行的函数  传的值  回调函数
    p.close()
    p.join()

结果:  回调函数会接收 上面函数1的返回值,从打印的进程号可以看出,回调函数是在主进程中执行的。

原文地址:https://www.cnblogs.com/wangdianchao/p/12088172.html