博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Python对进程Multiprocessing子进程返回值
阅读量:5894 次
发布时间:2019-06-19

本文共 3054 字,大约阅读时间需要 10 分钟。

hot3.png

在实际使用多进程的时候,可能需要获取到子进程运行的返回值。如果只是用来存储,则可以将返回值保存到一个数据结构中;如果需要判断此返回值,从而决定是否继续执行所有子进程,则会相对比较复杂。另外在Multiprocessing中,可以利用Process与Pool创建子进程,这两种用法在获取子进程返回值上的写法上也不相同。这篇中,我们直接上代码,分析多进程中获取子进程返回值的不同用法,以及优缺点。

初级用法(Pool)

目的:存储子进程返回值

说明:如果只是单纯的存储子进程返回值,则可以使用Pool的apply_async异步进程池;当然也可以使用Process,用法与threading中的相同,这里只介绍前者。

实例:当进程池中所有子进程执行完毕后,输出每个子进程的返回值。

from multiprocessing import Pooldef test(p):         return pif __name__=="__main__":    pool = Pool(processes=10)    result=[]    for i  in xrange(50000):       '''       for循环执行流程:       (1)添加子进程到pool,并将这个对象(子进程)添加到result这个列表中。(此时子进程并没有运行)       (2)执行子进程(同时执行10个)       '''       result.append(pool.apply_async(test, args=(i,)))#维持执行的进程总数为10,当一个进程执行完后添加新进程.           pool.join()    '''    遍历result列表,取出子进程对象,访问get()方法,获取返回值。(此时所有子进程已执行完毕)    '''    for i in result:        print i.get()

错误写法:

for i  in xrange(50000):   t=pool.apply_async(test, args=(i,)))   print t.get()

说明:这样会造成阻塞,因为get()方法只能等子进程运行完毕后才能调用成功,否则会一直阻塞等待。如果写在for循环内容,相当于变成了同步,执行效率将会非常低。

高级用法(Pool)

目的:父进程实时获取子进程返回值,以此为标记结束所有进程。

实例(一)

执行子进程的过程中,不断获取返回值并校验,如果返回值为True则结果所有进程。

from multiprocessing import Poolimport Queueimport timedef test(p):    time.sleep(0.001)    if p==10000:        return True    else:        return Falseif __name__=="__main__":    pool = Pool(processes=10)    q=Queue.Queue()    for i  in xrange(50000):    	'''    	将子进程对象存入队列中。    	'''        q.put(pool.apply_async(test, args=(i,)))#维持执行的进程总数为10,当一个进程执行完后添加新进程.           '''    因为这里使用的为pool.apply_async异步方法,因此子进程执行的过程中,父进程会执行while,获取返回值并校验。    '''    while 1:        if q.get().get():            pool.terminate() #结束进程池中的所有子进程。            break    pool.join()

说明:总共要执行50000个子进程(并发数量为10),当其中一个子进程返回True时,结束进程池。因为使用了apply_async为异步进程,因此在执行完for循环的添加子进程操作后(只是添加并没有执行完所有的子进程),可以直接执行while代码,实时判断子进程返回值是否有True,有的话结束所有进程。

优点:不必等到所有子进程结束再结束程序,只要得到想要的结果就可以提前结束,节省资源。

不足:当需要执行的子进程非常大时,不适用,因为for循环在添加子进程时,要花费很长的时间,虽然是异步,但是也需要等待for循环添加子进程操作结束才能执行while代码,因此会比较慢。

实例(二)

多线程+多进程,添加执行子进程的过程中,不断获取返回值并校验,如果返回值为True则结果所有进程。

from multiprocessing import Poolimport Queueimport threadingimport timedef test(p):    time.sleep(0.001)    if p==10000:        return True    else:        return Falseif __name__=="__main__":    result=Queue.Queue() #队列    pool = Pool()    def pool_th():        for i  in xrange(50000000): ##这里需要创建执行的子进程非常多            try:                result.put(pool.apply_async(test, args=(i,)))            except:                break    def result_th():        while 1:            a=result.get().get() #获取子进程返回值            if a:                pool.terminate() #结束所有子进程                break    '''    利用多线程,同时运行Pool函数创建执行子进程,以及运行获取子进程返回值函数。    '''    t1=threading.Thread(target=pool_th)    t2=threading.Thread(target=result_th)    t1.start()    t2.start()    t1.join()    t2.join()    pool.join()

执行流程:利用多线程,创建一个执行pool_th函数线程,一个执行result_th函数线程,pool_th函数用来添加进程池,开启进程执行功能函数并将子进程对象存入队列,而result_th()函数用来不停地从队列中取子进程对象,调用get()方法获取返回值。等发现其中存在子进程的返回值为True时,结束所有进程,最后结束线程。

优点:弥补了实例(一)的不足,即使for循环的子进程数量很多,也能提高性能,因为for循环与判断子进程返回值同时进行。

转载于:https://my.oschina.net/liuyuantao/blog/1154506

你可能感兴趣的文章
Apache2.4.33安装无systemctl/service status/state显示
查看>>
花花世界花家姐 舒淇:花花世界花我不会倒追
查看>>
全栈数据之数据挖掘的33个知识点整理
查看>>
Docker的系统资源限制及验证
查看>>
C++基础教程
查看>>
在大公司呆5年,你就废了
查看>>
mac mamp mysql no start servel
查看>>
openflow学习日记
查看>>
指定备份或还原操作在遇到错误后是继续还是停止 (SQL Server)
查看>>
文本处理工具及正则表达式
查看>>
linux 编写shell管理脚本01
查看>>
快节奏的多人游戏同步 - Part 3
查看>>
pyqt sqlite sql查询 如何处理 like语句 百分号
查看>>
apache 日志分析
查看>>
Git常用命令
查看>>
c++实现顺序循环队列结构,简易队列
查看>>
让Putty中显示中文的不再乱码(转)
查看>>
angularjs 与 jQuery 的Document ready
查看>>
Storm 实战:构建大数据实时计算
查看>>
solr(一)---介绍与安装
查看>>