进程池

在利用Python进行系统管理的时候,特别是同时操作多个文件目录,或者远程控制多台主机,并行操作可以节约大量的时间。多进程是实现并发的手段之一,需要注意的问题是:

1.很明显需要并发执行的任务通常要远大于核数
2.一个操作系统不可能无限开启进程,通常有几个核就开几个进程
3.进程开启过多,效率反而会下降(开启进程是需要占用系统资源的,而且开启多余核数目的进程也无法做到并行)
例如当被操作对象数目不大时,可以直接利用multiprocessing中的Process动态成生多个进程,十几个还好,但如果是上百个,上千个。。。手动的去限制进程数量却又太过繁琐,此时可以发挥进程池的功效。

我们就可以通过维护一个进程池来控制进程数目,比如httpd的进程模式,规定最小进程数和最大进程数... 

ps:对于远程过程调用的高级应用程序而言,应该使用进程池,Pool可以提供指定数量的进程,供用户调用,当有新的请求提交到pool中时,如果池还没有满,那么就会创建一个新的进程用来执行该请求;但如果池中的进程数已经达到规定最大值,那么该请求就会等待,直到池中有进程结束,就重用进程池中的进程。

import multiprocessing,time
def foo(num):
    print(num)
    time.sleep(1)
    return num+1
if __name__ == '__main__':
    pool=multiprocessing.Pool(processes=5)#令进程池执行的最大进程数为5,维持执行的进程总数为processes,当一个进程执行完毕后会添加新的进程进去
    res_l=[]
    for i in range(50):
        #res=pool.apply(func=foo,args=(i,))#apply方法是同步的,它会在执行完一个函数立即得到return结果(没有get方法),然后才会执行下一个,类似于串行
        res=pool.apply_async(func=foo,args=(i,))#apply_async是异步的,不会立即得到return结果,而是ApplyResult类的实例,需要用get()函数获取结果
        res_l.append(res)

    pool.close()   #关闭进程池,防止进一步操作关闭进程池,防止进一步操作
    pool.join()    #等待所有工作进程退出。此方法只能在close()或teminate()之后调用
                   #使用异步apply_async如果没有后面的join,或get,则程序整体结束,进程池中的任务还没来得及全部执行完也都跟着主进程一起结束了

    for res in res_l:
        print('-->',res) #apply得到的是return值,apply_async得到的是applyresult的实例

    for res in res_l:
        print('-->',res.get()) #只有apply_async才有get方法,得到return值
    print('end...')

回调函数

需要回调函数的场景:进程池中任何一个任务一旦处理完了,就立即告知主进程:我好了额,你可以处理我的结果了。主进程则调用一个函数去处理该结果,该函数即回调函数

import multiprocessing,time,os
def foo(num):
    print(num)
    time.sleep(1)
    return num+1,os.getpid()
def bar(res):
    print('bar pid is %s'%(os.getpid()))
    print('%s result is %s'%(res[1],res[0]))
if __name__ == '__main__':
    pool=multiprocessing.Pool(processes=5)
    res_l=[]
    for i in range(50):
        #res=pool.apply(func=foo,args=(i,))
        res=pool.apply_async(func=foo,args=(i,),callback=bar)#callback回调函数,在进程池中的一个任务执行完后,主程序会调用回调函数对任务的返回值进行处理
        res_l.append(res)                                    #callback函数是由主程序调用的,可以由pid看出
    pool.close()   
    pool.join()     
    print(os.getpid())


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值