【Python】进程池

来源:互联网 发布:python 2.7 转2.6 编辑:程序博客网 时间:2024/06/08 04:06

进程池Pool

当需要创建的子进程数量不多时,可以直接利用multiprocessing中的Process动态成生多个进程,但如果是上百甚至上千个目标,手动的去创建进程的工作量巨大,此时就可以用到multiprocessing模块提供的Pool方法。

初始化Pool时,可以指定一个最大进程数,当有新的请求提交到Pool中时,如果池还没有满,那么就会创建一个新的进程用来执行该请求;但如果池中的进程数已经达到指定的最大值,那么该请求就会等待,直到池中有进程结束,才会用之前的进程来执行新的任务,请看下面的实例:

# -*- coding:utf-8 -*-from multiprocessing import Poolimport os, time, randomdef worker(msg):    t_start = time.time()    print("%s开始执行,进程号为%d" % (msg,os.getpid()))    # random.random()随机生成0~1之间的浮点数    time.sleep(random.random()*2)     t_stop = time.time()    print(msg,"执行完毕,耗时%0.2f" % (t_stop-t_start))po = Pool(3)  # 定义一个进程池,最大进程数3for i in range(0,10):    # Pool().apply_async(要调用的目标,(传递给目标的参数元祖,))    # 每次循环将会用空闲出来的子进程去调用目标    po.apply_async(worker,(i,))print("----start----")po.close()  # 关闭进程池,关闭后po不再接收新的请求po.join()  # 等待po中所有子进程执行完成,必须放在close语句之后print("-----end-----")

运行结果:

----start----0开始执行,进程号为214661开始执行,进程号为214682开始执行,进程号为214670 执行完毕,耗时1.013开始执行,进程号为214662 执行完毕,耗时1.244开始执行,进程号为214673 执行完毕,耗时0.565开始执行,进程号为214661 执行完毕,耗时1.686开始执行,进程号为214684 执行完毕,耗时0.677开始执行,进程号为214675 执行完毕,耗时0.838开始执行,进程号为214666 执行完毕,耗时0.759开始执行,进程号为214687 执行完毕,耗时1.038 执行完毕,耗时1.059 执行完毕,耗时1.69-----end-----

multiprocessing.Pool常用函数解析:

  • apply_async(func[, args[, kwds]]) :使用非阻塞方式调用func(并行执行,堵塞方式必须等待上一个进程退出才能执行下一个进程),args为传递给func的参数列表,kwds为传递给func的关键字参数列表;
  • close():关闭Pool,使其不再接受新的任务;
  • terminate():不管任务是否完成,立即终止;
  • join():主进程阻塞,等待子进程的退出, 必须在close或terminate之后使用;

进程池中的Queue

如果要使用Pool创建进程,就需要使用multiprocessing.Manager()中的Queue(),而不是multiprocessing.Queue(),否则会得到一条如下的错误信息:

RuntimeError: Queue objects should only be shared between processes through inheritance.

下面的实例演示了进程池中的进程如何通信:

# -*- coding:utf-8 -*-# 修改import中的Queue为Managerfrom multiprocessing import Manager,Poolimport os,time,randomdef reader(q):    print("reader启动(%s),父进程为(%s)" % (os.getpid(), os.getppid()))    for i in range(q.qsize()):        print("reader从Queue获取到消息:%s" % q.get(True))def writer(q):    print("writer启动(%s),父进程为(%s)" % (os.getpid(), os.getppid()))    for i in "itcast":        q.put(i)if __name__=="__main__":    print("(%s) start" % os.getpid())    q = Manager().Queue()  # 使用Manager中的Queue    po = Pool()    po.apply_async(writer, (q,))    time.sleep(1)  # 先让上面的任务向Queue存入数据,然后再让下面的任务开始从中取数据    po.apply_async(reader, (q,))    po.close()    po.join()    print("(%s) End" % os.getpid())

运行结果:

(11095) startwriter启动(11097),父进程为(11095)reader启动(11098),父进程为(11095)reader从Queue获取到消息:ireader从Queue获取到消息:treader从Queue获取到消息:creader从Queue获取到消息:areader从Queue获取到消息:sreader从Queue获取到消息:t(11095) End
阅读全文
'); })();
0 0
原创粉丝点击
热门IT博客
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 新股买 如何卖股票 股票交易如何收费 股票如何看盘 股票几点可以买卖 股票怎么卖不出去 股票账户忘记了怎么办 股票怎么算收益 怎么看股票的基本面 股票怎么卖不了 怎么选好股票 创业板怎么开通 创业板是什么意思 股票怎么开通创业板 怎么区分创业板股票 如何开通创业板 创业板代码 新三板股票怎么买卖 如何开通创业板交易 100元怎么玩股票 创业板开通条件 怎么开通创业板权限 创业板股票一览表 股票开 怎样才能申购新股 汽车必须买的保险 车子一般买哪些保险 买新车上什么网 汽车必须买什么保险 汽车一般买哪些保险 车子保险买哪些 汽车保险买哪些 汽车怎么买保险划算 汽车保险买什么好 新手买车买什么保险 买大车 汽车保险必须买哪些 汽车保险在哪买 一般汽车保险买哪些 机动车保险怎么买 小汽车保险怎么买