concurrent.futures模块使用
一、概念总结
1-1 池:控制进程数或线程数的概念。
服务器开启的进程数或线程数,会随并发的客户端数目单调递增。会产生巨大的压力于服务器,于是使用“池”的概念,对服务端开启的进程数或线程数加以控制
- - 进程池:用来存放进程的‘池’
- - 线程池:用来存放线程的‘池’
1-2 同步&异步调用:提交任务的两种方式
- - 同步调用:提交任务,原地等待任务执行结束,拿到任务返回结果。再执行下一行代码,会导致任务串行执行。
- - 异步调用:提交任务,不进行原地等待,直接执行下一行代码,任务并发执行。
1-3 阻塞&非阻塞:程序的运行状态
- - 阻塞:程序遇到IO操作等,进行原地等待,即阻塞态
- - 非阻塞:程序未遭遇IO操作等,不进行等待,即运行态、就绪态
二、concurrent.futures 模块实现池
2-0 concurrent.futures基本总结
- concurrent.futures模块提供了高度封装的异步调用接口
- ThreadPoolExecutor:线程池,提供异步调用
- ProcessPoolExecutor: 进程池,提供异步调用
2-0-1 基本方法(进程池和线程池都适用)
submit(fn, *args, **kwargs) # 异步提交任务 ''' !!!注意:submit提交后返回的结果是一个future对象,需要使用future对象.result才能获取想要的字符串等结果 '''map(func, *iterables, timeout=None, chunksize=1) # 取代for循环submit的操作shutdown(wait=True) ''' 相当于进程池的pool.close()+pool.join()操作 wait=True,等待池内所有任务执行完毕回收完资源后才继续 wait=False,立即返回,并不会等待池内的任务执行完毕 但不管wait参数为何值,整个程序都会等到所有任务执行完毕 submit和map必须在shutdown之前 '''result(timeout=None) # 取得结果add_done_callback(fn) # 回调函数
2-1 进程池
2-1-1 进程池的两种任务提交方式
方式一、同步调用方式
from concurrent.futures import ProcessPoolExecutor import time, random, osdef task(name):print('%s %s is running' % (name, os.getpid()))time.sleep(random.randint(1, 3))if __name__ == '__main__':p = ProcessPoolExecutor(4) # 设置进程池内进程数for i in range(10):# 同步调用方式,调用和等值。obj = p.submit(task, '进程pid:') # 传参方式 (任务名,参数),参数使用位置参数或者关键字参数res = obj.result()p.shutdown(wait=True) # 关闭进程池的入口,等待池内任务运行结束print('主')
方式二、异步调用方式
from concurrent.futures import ProcessPoolExecutor import time, random, osdef task(name):print('%s %s is running' % (name, os.getpid()))time.sleep(random.randint(1, 3))if __name__ == '__main__':p = ProcessPoolExecutor(4) # 设置进程池内进程数for i in range(10):# 异步调用方式,只调用,不等值p.submit(task, '进程pid:') # 传参方式 (任务名,参数),参数使用位置参数或者关键字参数p.shutdown(wait=True) # 关闭进程池的入口,等待池内任务运行结束print('主')
2-1-2 进程池的同步调用方式
''' 同步调用方式解析:缺点:解耦合优点:速度慢 ''' from concurrent.futures import ProcessPoolExecutor import time, os import requestsdef get(url):print('%s GET %s' % (os.getpid(), url))time.sleep(3)response = requests.get(url)if response.status_code == 200:res = response.textelse:res = '下载失败'return resdef parse(res):time.sleep(1)print('%s 解析结果为%s' % (os.getpid(), len(res)))if __name__ == '__main__':urls = ['https://www.baidu.com','https://www.sina.com.cn','https://www.tmall.com','https://www.jd.com','https://www.python.org','https://www.openstack.org','https://www.baidu.com','https://www.baidu.com','https://www.baidu.com',]p = ProcessPoolExecutor(9)l = []start = time.time()for url in urls:future = p.submit(get, url)l.append(future)p.shutdown(wait=True)for future in l:parse(future.result())print('完成时间', time.time() - start)''' 6104 GET https://www.baidu.com 11096 GET https://www.sina.com.cn 6188 GET https://www.tmall.com 9224 GET https://www.jd.com 10376 GET https://www.python.org 7144 GET https://www.openstack.org 5516 GET https://www.baidu.com 9496 GET https://www.baidu.com 1100 GET https://www.baidu.com 14704 解析结果为2443 14704 解析结果为569114 14704 解析结果为233353 14704 解析结果为108550 14704 解析结果为48821 14704 解析结果为65099 14704 解析结果为2443 14704 解析结果为2443 14704 解析结果为2443 完成时间 19.062582969665527 '''
2-1-3 进程池的异步调用方式
''' 异步调用方式:缺点:存在耦合优点:速度快 ''' from concurrent.futures import ProcessPoolExecutor import time, os import requestsdef get(url):print('%s GET %s' % (os.getpid(), url))time.sleep(3)response = requests.get(url)if response.status_code == 200:res = response.textelse:res = '下载失败'parse(res)def parse(res):time.sleep(1)print('%s 解析结果为%s' % (os.getpid(), len(res)))if __name__ == '__main__':urls = ['https://www.baidu.com','https://www.sina.com.cn','https://www.tmall.com','https://www.jd.com','https://www.python.org','https://www.openstack.org','https://www.baidu.com','https://www.baidu.com','https://www.baidu.com',]p = ProcessPoolExecutor(9)start = time.time()for url in urls:future = p.submit(get, url)p.shutdown(wait=True)print('完成时间', time.time() - start)''' 11980 GET https://www.baidu.com 15308 GET https://www.sina.com.cn 14828 GET https://www.tmall.com 11176 GET https://www.jd.com 14792 GET https://www.python.org 14764 GET https://www.openstack.org 11096 GET https://www.baidu.com 13708 GET https://www.baidu.com 2080 GET https://www.baidu.com 14828 解析结果为233353 11176 解析结果为108569 11980 解析结果为2443 15308 解析结果为569124 11096 解析结果为2443 13708 解析结果为2443 2080 解析结果为2443 14764 解析结果为65099 14792 解析结果为48821 完成时间 7.404443979263306 '''
2-1-4 进程池,异步调用+回调函数:解决耦合,速度慢
''' 异步调用 + 回调函数 :解决耦合,但速度慢 ''' from concurrent.futures import ProcessPoolExecutor import time, os import requestsdef get(url):print('%s GET %s' % (os.getpid(), url))time.sleep(3)response = requests.get(url)if response.status_code == 200:res = response.textelse:res = '下载失败'return resdef parse(future):time.sleep(1)# 传入的是个对象,获取返回值 需要进行result操作res = future.result()print('%s 解析结果为%s' % (os.getpid(), len(res)))if __name__ == '__main__':urls = ['https://www.baidu.com','https://www.sina.com.cn','https://www.tmall.com','https://www.jd.com','https://www.python.org','https://www.openstack.org','https://www.baidu.com','https://www.baidu.com','https://www.baidu.com',]p = ProcessPoolExecutor(9)start = time.time()for url in urls:future = p.submit(get, url)# 模块内的回调函数方法,parse会使用future对象的返回值,对象返回值是执行任务的返回值future.add_done_callback(parse)p.shutdown(wait=True)print('完成时间', time.time() - start) ''' 3960 GET https://www.baidu.com 14320 GET https://www.sina.com.cn 1644 GET https://www.tmall.com 196 GET https://www.jd.com 13512 GET https://www.python.org 7356 GET https://www.openstack.org 14952 GET https://www.baidu.com 9528 GET https://www.baidu.com 11940 GET https://www.baidu.com 15292 解析结果为233360 15292 解析结果为108543 15292 解析结果为2443 15292 解析结果为2443 15292 解析结果为2443 15292 解析结果为2443 15292 解析结果为569140 15292 解析结果为48821 15292 解析结果为65099 完成时间 14.311698913574219 '''
2-2 线程池:异步+回调 ---- IO密集型主要使用方式
'''线程池:执行操作为谁有空谁执行''' from concurrent.futures import ThreadPoolExecutor from threading import current_thread import time import requestsdef get(url):print('%s GET %s' % (current_thread().name, url))time.sleep(3)response = requests.get(url)if response.status_code == 200:res = response.textelse:res = '下载失败'return resdef parse(future):time.sleep(1)res = future.result()print('%s 解析结果为%s' % (current_thread().name, len(res)))if __name__ == '__main__':urls = ['https://www.baidu.com','https://www.sina.com.cn','https://www.tmall.com','https://www.jd.com','https://www.python.org','https://www.openstack.org','https://www.baidu.com','https://www.baidu.com','https://www.baidu.com',]# 线程池内线程数p = ThreadPoolExecutor(4)start = time.time()for url in urls:future = p.submit(get, url)future.add_done_callback(parse)p.shutdown(wait=True)print('主', current_thread().name)print('完成时间', time.time() - start)''' <concurrent.futures.thread.ThreadPoolExecutor object at 0x00000172EB2053C8>_0 GET https://www.baidu.com <concurrent.futures.thread.ThreadPoolExecutor object at 0x00000172EB2053C8>_1 GET https://www.sina.com.cn <concurrent.futures.thread.ThreadPoolExecutor object at 0x00000172EB2053C8>_2 GET https://www.tmall.com <concurrent.futures.thread.ThreadPoolExecutor object at 0x00000172EB2053C8>_3 GET https://www.jd.com <concurrent.futures.thread.ThreadPoolExecutor object at 0x00000172EB2053C8>_2 解析结果为233360 <concurrent.futures.thread.ThreadPoolExecutor object at 0x00000172EB2053C8>_2 GET https://www.python.org <concurrent.futures.thread.ThreadPoolExecutor object at 0x00000172EB2053C8>_0 解析结果为2443 <concurrent.futures.thread.ThreadPoolExecutor object at 0x00000172EB2053C8>_0 GET https://www.openstack.org <concurrent.futures.thread.ThreadPoolExecutor object at 0x00000172EB2053C8>_3 解析结果为108554 <concurrent.futures.thread.ThreadPoolExecutor object at 0x00000172EB2053C8>_3 GET https://www.baidu.com <concurrent.futures.thread.ThreadPoolExecutor object at 0x00000172EB2053C8>_1 解析结果为569140 <concurrent.futures.thread.ThreadPoolExecutor object at 0x00000172EB2053C8>_1 GET https://www.baidu.com <concurrent.futures.thread.ThreadPoolExecutor object at 0x00000172EB2053C8>_1 解析结果为2443 <concurrent.futures.thread.ThreadPoolExecutor object at 0x00000172EB2053C8>_1 GET https://www.baidu.com <concurrent.futures.thread.ThreadPoolExecutor object at 0x00000172EB2053C8>_3 解析结果为2443 <concurrent.futures.thread.ThreadPoolExecutor object at 0x00000172EB2053C8>_2 解析结果为48821 <concurrent.futures.thread.ThreadPoolExecutor object at 0x00000172EB2053C8>_1 解析结果为2443 <concurrent.futures.thread.ThreadPoolExecutor object at 0x00000172EB2053C8>_0 解析结果为65099 主 MainThread 完成时间 14.592755317687988 '''
concurrent.futures模块使用相关推荐
- concurrent.futures模块(进程池线程池)
1.线程池的概念 由于python中的GIL导致每个进程一次只能运行一个线程,在I/O密集型的操作中可以开启多线程,但是在使用多线程处理任务时候,不是线程越多越好,因为在线程切换的时候,需要切换上下文 ...
- python线程池模块_Python并发编程之线程池/进程池--concurrent.futures模块
一.关于concurrent.futures模块 Python标准库为我们提供了threading和multiprocessing模块编写相应的多线程/多进程代码,但是当项目达到一定的规模,频繁创建/ ...
- 《转载》Python并发编程之线程池/进程池--concurrent.futures模块
本文转载自 Python并发编程之线程池/进程池--concurrent.futures模块 一.关于concurrent.futures模块 Python标准库为我们提供了threading和mul ...
- python实现多线程的三种方法threading.Thread(模块)的继承实现和函数实现;以及concurrent.futures模块的线程池实现
1.threading.Thread模块继承实现: import threading import timeclass TestThread(threading.Thread):def __init_ ...
- Python3.2+ 的 concurrent.futures 模块,利用 multiprocessing 实现高并发。
From:https://www.cnblogs.com/weihengblog/p/9812110.html concurrent.futures 官方文档:https://docs.python. ...
- Python 中 concurrent.futures 模块使用说明
Python 中 concurrent.futures 模块使用说明 转载请注明出处:https://blog.csdn.net/jpch89/article/details/87643972 文章目 ...
- python线程池模块_python并发编程之进程池,线程池,协程(Python标准模块--concurrent.futures(并发未来))...
需要注意一下 不能无限的开进程,不能无限的开线程 最常用的就是开进程池,开线程池.其中回调函数非常重要 回调函数其实可以作为一种编程思想,谁好了谁就去掉 只要你用并发,就会有锁的问题,但是你不能一直去 ...
- Python全栈学习笔记day 40.5+:线程池和线程池的Python标准模块--concurrent.futures
Python标准模块--concurrent.futures 源码:https://docs.python.org/dev/library/concurrent.futures.html #1 介绍: ...
- python并发模块之concurrent.futures(一)
Python3.2开始,标准库为我们提供了concurrent.futures模块,它提供了ThreadPoolExecutor和ProcessPoolExecutor两个类,实现了对threadin ...
最新文章
- 阿里全资收购一家核心技术公司,中科院大牛带队加盟
- OkHttp3的连接池及连接建立过程分析
- 题解【黑匣子_NOI导刊2010提高(06)】(洛谷P1801)
- linux共享数据,使用Linux共享数据对象
- django开发环境搭建
- 关于基类和子类构造函数的问题
- (对拍配套)随机生成数据
- linux反编译java_linux系统上如何反编译.class文件
- C# TeeChart使用心得,干货
- YUY2和MJPG视频编码格式区别
- BW数据加载后不能实时刷新到水晶易表解决方法
- LitsModer —— 开发日志(上)
- 贸易融资名词解析:出口押汇与进口押汇
- geany配置python_在python虚拟环境中使用geany
- 利用wifi对用户进行网络监控
- 2020年有寓意的领证日期_2020年领证日期怎么选
- 计算机英语专业被动语态,英语专业四级考试
- 一生的读书计划——影响中国历史进程的中国名人2
- Visual Studio的正确打开方式|9中种常见错误
- 硬盘检测软件测试培训,认识专业的考机工具PassMark BurnInTest_软件测试_软件测试培训_软件测试频道_中国IT实验室...