线程池,queue模块增加用法
1 同一个进程内的队列(多线程) import queue queue.Queue() 先进先出 queue.LifoQueue() 后进先出 queue.PriorityQueue() 优先级队列 优先级队列 q = queue.PriorityQueue() q.put() 接收的是一个元组 元组中第一个参数是:表示当前数据的优先级 元组中第二个参数是:需要存放到队列中的数据 优先级的比较(首先保证整个队列中,所有表示优先级的东西类型必须一致) 如果都是int,比数值的大小 如果都是str,比较字符串的大小(从第一个字符的ASCII码开始比较)代码:
from multiprocessing import Queue# 是用于多进程的队列,就是专门用来做进程间通信(IPC)。import queue# 是用于同一进程内的队列,不能做多进程之间的通信 q = queue.Queue() # 先进先出q.put(1)q.put(2)q.put(3)print(q.get())print(q.get()) q = queue.LifoQueue() # 后进先出的队列q.put(1)q.put(2)q.put(3)print(q.get()) q = queue.PriorityQueue()# 优先级队列,put()方法接收的是一个元组(),第一个位置是优先级,第二个位置是数据# 优先级如果是数字,直接比较数值# 如果是字符串,是按照 ASCII 码比较的。当ASCII码相同时,会按照先进先出的原则q.put((1,'abc'))q.put((5,'qwe'))q.put((-5,'zxc'))print(q.get())print(q.get())#print(chr(48))
2 线程池 在一个池子里,放固定数量的线程,这些线程等待任务,一旦有任务来,就有线程自发的去执行任务。 # concurrent.futures 这个模块是异步调用的机制# concurrent.futures 提交任务都是用submit# for + submit 多个任务的提交# shutdown 是等效于Pool中的close+join,是指不允许再继续向池中增加任务,然后让父进程(线程)等待池中所有进程执行完所有任务。进程池线程池效率对比代码:
from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutorfrom multiprocessing import Pool# from multiprocessing import Pool.apply / apply_async
import time
def func(num): sum = 0 for i in range(num): sum += i ** 2 print(sum)
if __name__ == '__main__':
pool的进程池的效率演示 p = Pool(5) start = time.time() for i in range(100): p.apply_async(func,args=(i,)) p.close() p.join() print('Pool进程池的效率时间是%s'%(time.time() - start))
多进程的效率演示 tp = ProcessPoolExecutor(5) start = time.time() for i in range(100): tp.submit(func, i) tp.shutdown() # 等效于 进程池中的 close + join print('进程池的消耗时间为%s' % (time.time() - start))
多线程的效率 tp = ThreadPoolExecutor(20) start = time.time() for i in range(1000): tp.submit(func,i) tp.shutdown()# 等效于 进程池中的 close + join print('线程池的消耗时间为%s'%(time.time() - start))
结果:针对计算密集的程序来说 不管是Pool的进程池还是ProcessPoolExecutor()的进程池,执行效率相当 ThreadPoolExecutor 的效率要差很多 所以 当计算密集时,使用多进程。
如何把多个任务扔进池中? 要么使用for + submit的方式去提交多个任务 要么直接使用map(func,iterable)方式去提交多个任务
多任务提交代码:
from concurrent.futures import ThreadPoolExecutorimport time def func(num): sum = 0 for i in range(num): sum += i ** 2 print(sum) t = ThreadPoolExecutor(20)start = time.time()t.map(func,range(1000))# 提交多个任务给池中。 等效于 for + submitt.shutdown()print(time.time() - start)
不同的方式提交多个任务(for+submit 或者 map),拥有不同的拿结果的方式 如果是for+submit的方式提交任务,拿结果用result方法 如果是map的方式提交任务,结果是一个生成器,采用__next__()的方式去拿结果线程池的返回值代码:
from concurrent.futures import ThreadPoolExecutorimport time def func(num): sum = 0 # time.sleep(5) # print(num) # 异步的效果 for i in range(num): sum += i ** 2 return sum t = ThreadPoolExecutor(20) # 下列代码是用map的方式提交多个任务,对应 拿结果的方法是__next__() 返回的是一个生成器对象res = t.map(func,range(1000))t.shutdown()print(res.__next__())print(res.__next__())print(res.__next__())print(res.__next__()) 下列代码是用for + submit提交多个任务的方式,对应拿结果的方法是resultres_l = []for i in range(1000): re = t.submit(func,i) res_l.append(re)# t.shutdown()[print(i.result()) for i in res_l]在Pool进程池中拿结果,是用get方法。 在ThreadPoolExecutor里边拿结果是用result方法
关于回调函数,不管是Pool进程池的方式,还是ProcessPoolExecutor的方式开启进程池, 回调函数都是由父进程调用关于回调函数,ThreadPoolExecutor 回调函数是子线程调用回调函数代码:
from concurrent.futures import ProcessPoolExecutor (进程池回调函数)# 不管是ProcessPoolExecutor的进程池 还是Pool的进程池,回调函数都是父进程调用的。import osimport requests def func(num): sum = 0 for i in range(num): sum += i ** 2 return sum def call_back_fun(res): # print(res.result(),os.getpid()) print(os.getpid()) if __name__ == '__main__': print(os.getpid()) t = ProcessPoolExecutor(20) for i in range(1000): t.submit(func,i).add_done_callback(call_back_fun) t.shutdown()
from threading import Thread (线程池回调函数)from threading import current_thread #相当于线程号from concurrent.futures import ThreadPoolExecutorimport timedef func(i): sum = 0 sum += i time.sleep(1) print('这是在子线程中',current_thread()) return sum
def call_back(sum): time.sleep(1) print('这是在回调函数中',sum.result(),current_thread())
if __name__ == '__main__': t = ThreadPoolExecutor(5) for i in range(10): t.submit(func,i).add_done_callback(call_back) t.shutdown() print('这是在主线程中',current_thread())
线程池,queue模块增加用法的更多相关文章
- Python程序中的线程操作(线程池)-concurrent模块
目录 Python程序中的线程操作(线程池)-concurrent模块 一.Python标准模块--concurrent.futures 二.介绍 三.基本方法 四.ProcessPoolExecut ...
- SpringBoot项目框架下ThreadPoolExecutor线程池+Queue缓冲队列实现高并发中进行下单业务
主要是自己在项目中(中小型项目) 有支付下单业务(只是办理VIP,没有涉及到商品库存),目前用户量还没有上来,目前没有出现问题,但是想到如果用户量变大,下单并发量变大,可能会出现一系列的问题,趁着空闲 ...
- python3 线程池-threadpool模块与concurrent.futures模块
多种方法实现 python 线程池 一. 既然多线程可以缩短程序运行时间,那么,是不是线程数量越多越好呢? 显然,并不是,每一个线程的从生成到消亡也是需要时间和资源的,太多的线程会占用过多的系统资源( ...
- Python之路(第四十六篇)多种方法实现python线程池(threadpool模块\multiprocessing.dummy模块\concurrent.futures模块)
一.线程池 很久(python2.6)之前python没有官方的线程池模块,只有第三方的threadpool模块, 之后再python2.6加入了multiprocessing.dummy 作为可以使 ...
- Java线程池ThreadPoolExecutor原理和用法
1.ThreadPoolExecutor构造方法 public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAli ...
- 详解线程池execute和submit用法
在使用线程池时,我们都知道线程池有两种提交任务的方式,那么他们有什么区别呢? 1.execute提交的是Runnable类型的任务,而submit提交的是Callable或者Runnable类型的任务 ...
- 线程池的极简用法——内置线程池multiprocessing
大家好,今天博主来分享一个线程池的小捷径--内置线程池的使用方法 一.背景 说道多线程,对变成层有了解的小伙伴一定不陌生,虽然不知道是什么但是也会从各大网站.面试分享等途径听说过.这里就不做过多的介绍 ...
- concurrent.futures模块(进程池/线程池)
需要注意一下不能无限的开进程,不能无限的开线程最常用的就是开进程池,开线程池.其中回调函数非常重要回调函数其实可以作为一种编程思想,谁好了谁就去掉 只要你用并发,就会有锁的问题,但是你不能一直去自己加 ...
- 线程池python
原创博文,转载请注明出处 今天在学习python进程与线程时,无意间发现了线程池threadpool模块,见官方文档. 模块使用非常简单,前提是得需要熟悉线程池的工作原理. 我们知道系统处理任务时,需 ...
随机推荐
- HDU 4647 Another Graph Game 想法类
解题思路:若没有边权,则对点权从大到小排序即可.. 考虑边,将边权拆成两半加到它所关联的两个点的点权中即可. ..因为当两个人分别选择不同的点时,这一权值将互相抵消. 以上摘自杭电的解题报告. 至于为 ...
- (4)logging(日志模块)
日志分成几个常用的级别 debug 10 代表程序调试过程中的信息 info 20 代表普通日志信息,用户的访问等等 warning 30 警告日志,有可能出错,但是目前还没出错的 error 40 ...
- CountDownLatch的简单理解
CountDownLatch的概念 CountDownLatch是一个同步工具类,用来协调多个线程之间的同步,或者说起到线程之间的通信(而不是用作互斥的作用). CountDownLatch能够使一个 ...
- 理解git
为了真正了解git,我们从底部.底层开始,了解git核心,知其然并知其所以然. 为什么要进行版本控制呢? 因为编写文件不可能一次到位,文件总是有不同的状态需要保存下来,方便以后出错回滚. git 是目 ...
- FastAdmin 开发第三天:安装 FastAdmin
环境安装安装好后就可以安装 FastAdmin 了. 根据文档说明安装步骤如下,推荐使用命令行安装: 克隆FastAdmin到你本地 git clone https://git.oschina.net ...
- ORA-32004 的错误处理
启动数据库时,收到了ORA-32004 的错误,错误多是一些过时且在当前版本中不在使用的参数,如果碰到类似的错误,只需要将其 reset即可. SQL> startup;ORA-32004: o ...
- 基于DRL和TORCS的自动驾驶仿真系统——之环境配置
基于DRL和TORCS的自动驾驶仿真系统 --之环境配置 玩TORCS和DRL差不多有一整年了,开始的摸爬滚打都是不断碰壁过来的,近来在参与CMU的DRL10703课程学习和翻译志愿者工作,也将自己以 ...
- !!!!!!!【unittest】unittest需要懂的的技术
https://docs.python.org/2/library/unittest.html
- signal简述
一个几乎是最简单的应用如下: #include <unistd.h> // for alarm() #include <signal.h> // for signal() #i ...
- PAT 乙级 1038 统计同成绩的学生C++版
1038. 统计同成绩学生(20) 时间限制 250 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN, Yue 本题要求读入N名学生的成绩,将 ...