进程池Pool

在利用Python进行系统管理的时候,特别是同时操作多个文件目录,或者远程控制多台主机,并行操作可以节约大量的时间。当被操作对象数目不大时,可以直接利用multiprocessing中的Process动态成生多个进程,但如果是上百个,上千个目标,手动的去限制进程数量却又太过繁琐,此时就可以用到multiprocessing模块提供的Pool方法。

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

一:使用进程池

例1:非阻塞

from multiprocessing import Pool

import os, time, random

def worker(name):

t_start = time.time()

print("%s开始执行,进程号为%d" % (name, os.getpid()))

# random.random()随机生成0~1之间的浮点数

time.sleep(random.random() * 2)

t_stop = time.time()

print(name, "执行完毕,耗时%0.2f" % (t_stop - t_start))

def main():

po = Pool(5) # 定义一个进程池,最大进程数5

# 往进程池中添加任务

for i in range(10):

# Pool.apply_async(要调用的目标,(传递给目标的参数元祖,))

# 每次循环将会用空闲出来的子进程去调用目标

po.apply_async(worker, (f'liang{i}',))

print("----start----")

po.close() # 关闭进程池,关闭后po不再接收新的请求

po.join() # 等待po中所有子进程执行完成,必须放在close语句之后

print("----all_done----")

if __name__ == '__main__':

main()

执行结果

----start----

liang0开始执行,进程号为10404

liang1开始执行,进程号为9920

liang2开始执行,进程号为13136

liang3开始执行,进程号为10180

liang4开始执行,进程号为7708

liang4 执行完毕,耗时0.57

liang5开始执行,进程号为7708

liang2 执行完毕,耗时1.20

liang6开始执行,进程号为13136

liang1 执行完毕,耗时1.33

liang7开始执行,进程号为9920

liang0 执行完毕,耗时1.34

liang8开始执行,进程号为10404

liang3 执行完毕,耗时1.96

liang9开始执行,进程号为10180

liang5 执行完毕,耗时1.73

liang9 执行完毕,耗时0.54

liang8 执行完毕,耗时1.28

liang7 执行完毕,耗时1.37

liang6 执行完毕,耗时1.88

----all_done----

函数解释:

apply_async(func[, args[, kwds]]) :使用非阻塞方式调用func(并行执行,堵塞方式必须等待上一个进程退出才能执行下一个进程),args为传递给func的参数列表, kwds为传递给func的关键字参数列表;

apply(func[, args[, kwds]]):使用阻塞方式调用func

close():关闭Pool,使其不再接受新的任务;

terminate():不管任务是否完成,立即终止;

join():主进程阻塞,等待子进程的退出, 必须在close或terminate之后使用;

执行说明:创建一个进程池pool,并设定进程的数量为5,range(10)会相继产生10个对象,10个对象被提交到pool中,因pool指定进程数为5,所以0、1、2、3、4会直接送到进程中执行,当其中一个执行完后才空出一个进程处理对象,继续去执行新的对象,所以会出现输出“liang5开始执行,进程号为7708”出现在"liang4 执行完毕,耗时0.57"后。因为为非阻塞,主函数会自己执行自个的,不搭理进程的执行,所以运行完for循环后直接输出“----start----”,主程序在pool.join()处等待各个进程的结束。

例2:阻塞

from multiprocessing import Pool

import os, time, random

def worker(name):

t_start = time.time()

print("%s开始执行,进程号为%d" % (name, os.getpid()))

# random.random()随机生成0~1之间的浮点数

time.sleep(random.random() * 2)

t_stop = time.time()

print(name, "执行完毕,耗时%0.2f" % (t_stop - t_start))

def main():

po = Pool(3) # 定义一个进程池,最大进程数3

# 往进程池中添加任务

for i in range(0, 5):

# Pool.apply_async(要调用的目标,(传递给目标的参数元祖,))

# 每次循环将会用空闲出来的子进程去调用目标

po.apply(worker, (f'liang{i}',))

print("----start----")

po.close() # 关闭进程池,关闭后po不再接收新的请求

po.join() # 等待po中所有子进程执行完成,必须放在close语句之后

print("----all_done----")

if __name__ == '__main__':

main()

输出

liang0开始执行,进程号为1976

liang0 执行完毕,耗时1.75

liang1开始执行,进程号为12624

liang1 执行完毕,耗时0.57

liang2开始执行,进程号为12444

liang2 执行完毕,耗时0.52

liang3开始执行,进程号为1976

liang3 执行完毕,耗时1.23

liang4开始执行,进程号为12624

liang4 执行完毕,耗时0.85

----start----

----all_done----

因为是阻塞,主函数会等待进程的执行,执行完之后才会继续往下,所以运行完所有进程后才输出“----start----”

例3、使用进程池,并返回结果

from multiprocessing import Pool

import os, time, random

def worker(name):

print("%s开始执行,进程号为%d" % (name, os.getpid()))

# random.random()随机生成0~1之间的浮点数

time.sleep(random.random() * 2)

return name,os.getpid()

def main():

po = Pool(3) # 定义一个进程池,最大进程数3

res=[]

# 往进程池中添加任务

for i in range(0, 5):

# Pool.apply_async(要调用的目标,(传递给目标的参数元祖,))

# 每次循环将会用空闲出来的子进程去调用目标

res.append(po.apply_async(worker, (f'liang{i}',)))

print("----start----")

po.close() # 关闭进程池,关闭后po不再接收新的请求

po.join() # 等待po中所有子进程执行完成,必须放在close语句之后

for result in res:

print(result.get()) #get()函数得出每个返回结果的值

print("----all_done----")

if __name__ == '__main__':

main()

输出结果:

----start----

liang0开始执行,进程号为14012

liang1开始执行,进程号为13000

liang2开始执行,进程号为14120

liang3开始执行,进程号为14012

liang4开始执行,进程号为14012

('liang0', 14012)

('liang1', 13000)

('liang2', 14120)

('liang3', 14012)

('liang4', 14012)

----all_done----

例4、多进程执行多个任务

from multiprocessing import Pool

import os, time, random

def worker1(name):

print("%s开始执行work1,进程号为%d" % (name, os.getpid()))

# random.random()随机生成0~1之间的浮点数

time.sleep(random.random() * 2)

def worker2(name):

print("%s开始执行work2,进程号为%d" % (name, os.getpid()))

# random.random()随机生成0~1之间的浮点数

time.sleep(random.random() * 2)

def worker3(name):

print("%s开始执行work3,进程号为%d" % (name, os.getpid()))

# random.random()随机生成0~1之间的浮点数

time.sleep(random.random() * 2)

def main():

po = Pool(4) # 定义一个进程池,最大进程数3

work_list=[worker1,worker2,worker3]

# 往进程池中添加任务

for work in work_list:

for i in range(3):

po.apply_async(work, (f'liang{i}',))

print("----start----")

po.close() # 关闭进程池,关闭后po不再接收新的请求

po.join() # 等待po中所有子进程执行完成,必须放在close语句之后

print("----all_done----")

if __name__ == '__main__':

main()

线程池4个线程执行3个任务,每个任务执行3次。

输出:

----start----

liang0开始执行work1,进程号为13088

liang1开始执行work1,进程号为4908

liang2开始执行work1,进程号为4200

liang0开始执行work2,进程号为8124

liang1开始执行work2,进程号为4908

liang2开始执行work2,进程号为13088

liang0开始执行work3,进程号为8124

liang1开始执行work3,进程号为4200

liang2开始执行work3,进程号为4908

----all_done----

二、进程池进程之间的通讯

进程池中进程的通讯队列

from multiprocessing import Pool, Manager

q = Manager().Queue()

import os

import time

from multiprocessing import Pool, Manager

def work(name, q):

time.sleep(1)

print(f"{name}:---{os.getpid()}---{q.get()}")

def main():

# 创建一个用于进程池通信的队列

q = Manager().Queue()

for i in range(1000):

q.put(f'data-{i}')

# 创建一个拥有五个进程的进程池

po = Pool(5)

# 往进程池中添加20个任务

for i in range(20):

po.apply_async(work, (f'liang{i}', q))

# close:关闭进程池(进程池停止接收任务)

po.close()

# 主进程等待进程池中的任务结束再往下执行

po.join()

if __name__ == '__main__':

main()

python进程池pool_python多任务--进程池Pool相关推荐

  1. Python 多进程笔记 — 启动进程的方式、守护进程、进程间通信、进程池、进程池之间通信、多进程生产消费模型

    1 面向过程启动多进程 Python 操作进程的类都定义在 multiprocessing 模块,该模块提供了一个 Process 类来代表一个进程对象,这个对象可以理解为是一个独立的进程,可以执行另 ...

  2. 学习笔记(33):Python网络编程并发编程-进程池线程池

    立即学习:https://edu.csdn.net/course/play/24458/296451?utm_source=blogtoedu 进程池与线程池: 一般应用在网站上,进程池或线程池最大的 ...

  3. python 协程池gevent.pool_进程池\线程池,协程,gevent

    目录 1. 进程池与线程池 2. 协程 3. gevent 4. 单线程下实现并发的套接字通信 首先写一个基于多线程的套接字 服务端: from socket import * from thread ...

  4. Python开发基础--- 进程间通信、进程池、协程

    进程间通信 进程彼此之间互相隔离,要实现进程间通信(IPC),multiprocessing模块支持两种形式:队列和管道,这两种方式都是使用消息传递的. 进程队列queue 不同于线程queue,进程 ...

  5. python多线程,多进程,线程池,进程池

    https://blog.csdn.net/somezz/article/details/80963760 python 多线程 线程(Thread)也叫轻量级进程,是操作系统能够进行运算调度的最小单 ...

  6. 多任务---进程、进程池

    实现多任务的另一种形式 程序是可以运行的,运行起来叫做进程,能够分配各种资源.(网络.显卡.鼠标.键盘.蓝牙-) 程序只有一个,但是进程可以多个. 使用进程实现多任务 import time impo ...

  7. Python多进程(一)进程及进程池

    进程 进程是操作系统分配资源的基本单元,是程序隔离的边界. 进程和程序 程序只是一组指令的集合,它本身没有任何运行的含义,它是静态的. 进程程序的执行实例,是动态的,有自己的生命周期,有创建有撤销,存 ...

  8. Python进程池及自定义进程

    Python进程池及自定义进程 微信关注公众号:夜寒信息 致力于为每一位用户免费提供更优质技术帮助与资源供给,感谢支持!     这次给大家分享Python的进程池及自定义进程,由于Python基础已 ...

  9. Python进程池,线程池,协程池

    线程池 import threading import time def myThread():for i in range(10):time.sleep()print('d') sep=thread ...

最新文章

  1. 推荐GitHub上几个比较热门的开源项目,记得收藏下!!!
  2. SLA 99.99%以上!饿了么实时计算平台3年演进历程
  3. ImportError: No module named sklearn.metrics
  4. 问题 L: 超超的中等意思
  5. python IDE--pycharm安装及使用
  6. 流程图外部数据内部数据图形_数据治理工具:基于SQL图形化数据血缘系统的实现和使用...
  7. STM32部分功能所在文件位置
  8. BOOST库介绍(八)——deadline_timer
  9. 使用R包qpdf用一行代码将多个pdf合并为一个pdf
  10. C语言中 两个分号啥意思,问什么C程序里总是提示缺少分号;,而明明有分号?...
  11. windowsPE系统的制作
  12. 帆软报表设置的参数不显示_FineReport报表工具显示格式和显示值的设置
  13. promise的意义和用法
  14. 公务卡引发多米诺效应 推动POS系统“繁荣”
  15. java实现文字识别营业执照识别(百度、讯飞)
  16. 基于ssm 流浪猫狗救助系统
  17. 人工智能对人类的机遇与挑战
  18. 【学习亚马逊AWS IOT体系有感---万物互联(物联网)】
  19. 【财富空间】陈春花:好公司就是要满足人们对美好生活的向往;技术如何驱动商业腾飞?...
  20. 使用H5Stream实现rtsp视频流播放,在Vue项目中 (无插件、可多视频源播放、亲测可用)

热门文章

  1. 替换WordPress调用的Google前端库为360镜像的库
  2. AIX errdemon 命令
  3. Java多线程同步Synchronized使用分析
  4. VS2005(c#)项目调试问题解决方案集锦
  5. DotNetNuke 框架总揽
  6. 获取泛型T的ClassT clazz
  7. 学成在线--6.CMS页面管理开发(删除页面)
  8. python99乘法表while翻译_Python学习之while练习--九九乘法表
  9. python2.7无法使用pip(安装easy_install)
  10. qtableview点击行将整行数据传过去_可以实时获取数据的Database Asset插件