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

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

import multiprocessing
import time
import os
import random def test1(msg):
t_start = time.time()
print("%s开始执行,进程号为%d" % (msg, os.getpid()))
time.sleep(random.random() * 2)
t_stop = time.time()
print("%s执行完成,耗时%.2f" % (msg, t_stop - t_start)) if __name__ == "__main__": po = multiprocessing.Pool(3)
for i in range(0, 10):
# Pool().apply_async(要调用的目标,(传递给目标的参数元祖,))
# 每次循环将会用空闲出来的子进程去调用目标
po.apply_async(test1, (i,)) print("-----start-----") po.close() # 关闭进程池,关闭后po不再接收新的请求
po.join() # 等待po中所有子进程执行完成,必须放在close语句之后 print("-----end-----")

运行结果:

-----start-----
0开始执行,进程号为40291
1开始执行,进程号为40292
2开始执行,进程号为40293
2执行完成,耗时0.59
3开始执行,进程号为40293
0执行完成,耗时1.21
4开始执行,进程号为40291
1执行完成,耗时1.56
5开始执行,进程号为40292
3执行完成,耗时1.58
6开始执行,进程号为40293
5执行完成,耗时1.36
7开始执行,进程号为40292
4执行完成,耗时1.73
8开始执行,进程号为40291
6执行完成,耗时1.34
9开始执行,进程号为40293
8执行完成,耗时0.71
9执行完成,耗时0.36
7执行完成,耗时1.21
-----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.

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

import os
import multiprocessing
import time def write(q):
print("write启动(%s),父进程为(%s)" % (os.getpid(), os.getppid()))
for i in "python":
q.put(i) def read(q):
print("read启动(%s),父进程为(%s)" % (os.getpid(), os.getppid()))
for i in range(q.qsize()):
print("read从Queue获取到消息:%s" % q.get(True)) if __name__ == "__main__":
print("(%s) start" % os.getpid())
q = multiprocessing.Manager().Queue()
po = multiprocessing.Pool()
po.apply_async(write, args=(q,)) time.sleep(2) po.apply_async(read, args=(q,))
po.close()
po.join() print("(%s) end" % os.getpid())

运行结果:

(41888) start
write启动(41894),父进程为(41888)
read启动(41895),父进程为(41888)
read从Queue获取到消息:p
read从Queue获取到消息:y
read从Queue获取到消息:t
read从Queue获取到消息:h
read从Queue获取到消息:o
read从Queue获取到消息:n
(41888) end

python进程池的更多相关文章

  1. python进程池:multiprocessing.pool

    本文转至http://www.cnblogs.com/kaituorensheng/p/4465768.html,在其基础上进行了一些小小改动. 在利用Python进行系统管理的时候,特别是同时操作多 ...

  2. python(进程池/线程池)

    进程池 import multiprocessing import time def do_calculation(data): print(multiprocessing.current_proce ...

  3. python进程池剖析(三)

    之前文章对python中进程池的原理.数据流以及应用从代码角度做了简单的剖析,现在让我们回头看看标准库中对进程池的实现都有哪些值得我们学习的地方.我们知道,进程池内部由多个线程互相协作,向客户端提供可 ...

  4. python进程池剖析(二)

    之前文章中介绍了python中multiprocessing模块中自带的进程池Pool,并对进程池中的数据结构和各个线程之间的合作关系进行了简单分析,这节来看下客户端如何对向进程池分配任务,并获取结果 ...

  5. python进程池剖析(一)

    python中两个常用来处理进程的模块分别是subprocess和multiprocessing,其中subprocess通常用于执行外部程序,比如一些第三方应用程序,而不是Python程序.如果需要 ...

  6. 万里长征第一步:Python进程池的一点点小坑

    # -*- coding: utf- -*- """ Created on Thu Mar :: @author: lilide """ # ...

  7. python 进程池的简单使用方法

    回到python,用一下python的进程池. 记得之前面试的时候,面试官问:你知道进程池的默认参数吗? 我没有回答上来,后来才知道,是有默认参数的.下面就看看它的默认参数 1. 不加参数 from ...

  8. python 进程池pool简单使用

    平常会经常用到多进程,可以用进程池pool来进行自动控制进程,下面介绍一下pool的简单使用. 需要主动是,在Windows上要想使用进程模块,就必须把有关进程的代码写if __name__ == ‘ ...

  9. python 进程池Pool以及Queue的用法

    import os,time,random from multiprocessing import Pool def task(name): print('正在运行的任务:%s,PID:(%s)'%( ...

随机推荐

  1. 利用正则+requests爬取猫眼电影信息

    import json # from multiprocessing import Pool import requests from requests.exceptions import Reque ...

  2. spring整合mybatis二种配置

    第一种: <!-- 配置sqlsession --> <bean id="sqlsessionFactory" class="org.mybatis.s ...

  3. 深入理解JVM(一)——基本原理

    前言 JVM一直是java知识里面进阶阶段的重要部分,如果希望在java领域研究的更深入,则JVM则是如论如何也避开不了的话题,本系列试图通过简洁易读的方式,讲解JVM必要的知识点. 运行流程 我们都 ...

  4. CSS3中的一些属性

    1. 可匹配部分字符串 2. box-sizing属性 3. CSS3多栏布局 1.可匹配部分字符串 /*^运算符,匹配字符串首部*/ a[href^='http://website'] /*$运算符 ...

  5. 深入浅出 Java 中的包装类

    前阵子,我们分享了<Java中的基本数据类型转换>这篇文章,对许多粉丝还是有带来帮助的,今天讲一下 Java 包装类的的由来,及自动装箱.拆箱的概念和原理. 什么是包装类型 Java 设计 ...

  6. Postgresql-模糊匹配大杀器

    # Postgresql-模糊匹配大杀器 ## 问题背景 随着pg越来越强大,abase目前已经升级到5.0(postgresql10.4),目前abase5.0继承了全文检索插件(zhparser) ...

  7. InnoDB多版本

    InnoDB是一个多版本的存储引擎:为了支持事务的一些特性诸如并发和回滚,它保持着被修改行的旧版本信息.这些信息被存储在一个被叫做“回滚段”的表空间中(跟Oracle中的回滚段类似).InnoDB在回 ...

  8. Android切换横竖屏不销毁前台Activity,也不影响后台Activity

    在切换屏幕方向的时候,Activity默认会走销毁->重建的生命周期,而有时候我们不希望如此,就需要做些额外的设置了: 1.在AndroidMainifest.xml中对应的Activity标签 ...

  9. newwork setup

    #-*-coding:utf-8-*- ######################################################################### # Copy ...

  10. vue-08-axios-get-post-跨域

    1, 安装 cnpm install axios --save 2, 在main.js中引入 import Axios from 'axios' // 挂在在Vue上Vue.prototype.$ax ...