一、概念总结

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模块使用相关推荐

  1. concurrent.futures模块(进程池线程池)

    1.线程池的概念 由于python中的GIL导致每个进程一次只能运行一个线程,在I/O密集型的操作中可以开启多线程,但是在使用多线程处理任务时候,不是线程越多越好,因为在线程切换的时候,需要切换上下文 ...

  2. python线程池模块_Python并发编程之线程池/进程池--concurrent.futures模块

    一.关于concurrent.futures模块 Python标准库为我们提供了threading和multiprocessing模块编写相应的多线程/多进程代码,但是当项目达到一定的规模,频繁创建/ ...

  3. 《转载》Python并发编程之线程池/进程池--concurrent.futures模块

    本文转载自 Python并发编程之线程池/进程池--concurrent.futures模块 一.关于concurrent.futures模块 Python标准库为我们提供了threading和mul ...

  4. python实现多线程的三种方法threading.Thread(模块)的继承实现和函数实现;以及concurrent.futures模块的线程池实现

    1.threading.Thread模块继承实现: import threading import timeclass TestThread(threading.Thread):def __init_ ...

  5. Python3.2+ 的 concurrent.futures 模块,利用 multiprocessing 实现高并发。

    From:https://www.cnblogs.com/weihengblog/p/9812110.html concurrent.futures 官方文档:https://docs.python. ...

  6. Python 中 concurrent.futures 模块使用说明

    Python 中 concurrent.futures 模块使用说明 转载请注明出处:https://blog.csdn.net/jpch89/article/details/87643972 文章目 ...

  7. python线程池模块_python并发编程之进程池,线程池,协程(Python标准模块--concurrent.futures(并发未来))...

    需要注意一下 不能无限的开进程,不能无限的开线程 最常用的就是开进程池,开线程池.其中回调函数非常重要 回调函数其实可以作为一种编程思想,谁好了谁就去掉 只要你用并发,就会有锁的问题,但是你不能一直去 ...

  8. Python全栈学习笔记day 40.5+:线程池和线程池的Python标准模块--concurrent.futures

    Python标准模块--concurrent.futures 源码:https://docs.python.org/dev/library/concurrent.futures.html #1 介绍: ...

  9. python并发模块之concurrent.futures(一)

    Python3.2开始,标准库为我们提供了concurrent.futures模块,它提供了ThreadPoolExecutor和ProcessPoolExecutor两个类,实现了对threadin ...

最新文章

  1. 阿里全资收购一家核心技术公司,中科院大牛带队加盟
  2. OkHttp3的连接池及连接建立过程分析
  3. 题解【黑匣子_NOI导刊2010提高(06)】(洛谷P1801)
  4. linux共享数据,使用Linux共享数据对象
  5. django开发环境搭建
  6. 关于基类和子类构造函数的问题
  7. (对拍配套)随机生成数据
  8. linux反编译java_linux系统上如何反编译.class文件
  9. C# TeeChart使用心得,干货
  10. YUY2和MJPG视频编码格式区别
  11. BW数据加载后不能实时刷新到水晶易表解决方法
  12. LitsModer —— 开发日志(上)
  13. 贸易融资名词解析:出口押汇与进口押汇
  14. geany配置python_在python虚拟环境中使用geany
  15. 利用wifi对用户进行网络监控
  16. 2020年有寓意的领证日期_2020年领证日期怎么选
  17. 计算机英语专业被动语态,英语专业四级考试
  18. 一生的读书计划——影响中国历史进程的中国名人2
  19. Visual Studio的正确打开方式|9中种常见错误
  20. 硬盘检测软件测试培训,认识专业的考机工具PassMark BurnInTest_软件测试_软件测试培训_软件测试频道_中国IT实验室...

热门文章

  1. java 连接多实例_Java如何连接多实例SQL Server?
  2. 【深入设计模式】装饰模式—什么是装饰模式?装饰模式在源码中的应用
  3. elasticsearch通用工具类
  4. 机器学习中的损失函数(Loss Function)介绍、说明
  5. box-shadow上下左右四个边框设置阴影样式
  6. java中如何反编译class文件
  7. 修改DNS—出现一个意外,不能完成更改
  8. 第7章 分析恶意的windows程序
  9. Shell语言(一)
  10. RHEL 7.8 64bit MYSQL linux-generic 8.0.20 初始化安装