concurrent包只有一个模块:

concurrent.futures - 启动并行任务

异步并行任务编程模块,提供一个高级的异步可执行的便利接口。

futures模块提供了2个池执行器

ThreadPoolExecutor 异步调用的线程池的Executor

ProcessPoolExecutor 异步调用的进程池的Executor

ThreadPoolExecutor对象

首先需要定义一个池的执行器对象,Executor类子类对象。

ThreadPoolExecutor(max_worker=1)     池中至多创建max_workers个线程的池来同时异步执行,返回Executor实例

submit(fn,*args,**kwargs)    提交执行的函数即参数,返回Future实例

shutdown(wait=True)    清理池

Future类方法:

result()    可以查看调用的返回的结果

done()     如果调用被成功的取消或者执行完成,返回True

canceled()    如果调用被成功的取消,返回True

running()     如果正在运行且不能被取消,返回True

cancel()     尝试取消调用。如果已经执行且不能取消返回False,否则返回True

result(timeout=None)   取返回的结果,超时为None,一直等待返回;超时设置到期,抛出concurrent.futures.TimeoutError异常

execption(timeout=None)   取返回的异常,超时为None,一直等待返回;超时设置到期,抛出conncurrent.futures.TimeoutError异常

1) 线程池并行异步执行:

  1. # 并行异步执行,线程 ThreadPoolExecutor
  2.  
  3. import threading
  4. import logging
  5. from concurrent import futures
  6. import time
  7. logging.basicConfig(level=logging.INFO,format="%(thread)s %(message)s")
  8.  
  9. def work(n): #工作函数
  10. logging.info('wokring-{}'.format(n))
  11. time.sleep(5)
  12. logging.info('end work-{}'.format(n))
  13.  
  14. executor = futures.ThreadPoolExecutor(3) #线程
  15.  
  16. fs = [] #线程池容器
  17.  
  18. for i in range(3):
  19. f = executor.submit(work,i) #提交执行的函数及参数
  20. fs.append(f)
  21.  
  22. for i in range(3,6):
  23. f = executor.submit(work,i)
  24. fs.append(f)
  25.  
  26. while True:
  27. time.sleep(2)
  28. logging.info(threading.enumerate())
  29.  
  30. flag = True
  31.  
  32. for f in fs:
  33. flag = flag and f.done() #调用是否被成功的取消或运行完成
  34.  
  35. if flag:
  36. executor.shutdown() #清理池
  37. logging.info(threading.enumerate())
  38. break
  39.  
  40. #运行结果:
  41. 123145331777536 wokring-0
  42. 123145337032704 wokring-1
  43. 123145342287872 wokring-2
  44. 4320629568 [<_MainThread(MainThread, started 4320629568)>, <Thread(Thread-1, started daemon 123145331777536)>, <Thread(Thread-2, started daemon 123145337032704)>, <Thread(Thread-3, started daemon 123145342287872)>]
  45. 4320629568 [<_MainThread(MainThread, started 4320629568)>, <Thread(Thread-1, started daemon 123145331777536)>, <Thread(Thread-2, started daemon 123145337032704)>, <Thread(Thread-3, started daemon 123145342287872)>]
  46. 123145331777536 end work-0
  47. 123145331777536 wokring-3
  48. 123145337032704 end work-1
  49. 123145337032704 wokring-4
  50. 123145342287872 end work-2
  51. 123145342287872 wokring-5
  52. 4320629568 [<_MainThread(MainThread, started 4320629568)>, <Thread(Thread-1, started daemon 123145331777536)>, <Thread(Thread-2, started daemon 123145337032704)>, <Thread(Thread-3, started daemon 123145342287872)>]
  53. 4320629568 [<_MainThread(MainThread, started 4320629568)>, <Thread(Thread-1, started daemon 123145331777536)>, <Thread(Thread-2, started daemon 123145337032704)>, <Thread(Thread-3, started daemon 123145342287872)>]
  54. 123145331777536 end work-3
  55. 123145342287872 end work-5
  56. 123145337032704 end work-4
  57. 4320629568 [<_MainThread(MainThread, started 4320629568)>, <Thread(Thread-1, started daemon 123145331777536)>, <Thread(Thread-2, started daemon 123145337032704)>, <Thread(Thread-3, started daemon 123145342287872)>]
  58. 4320629568 [<_MainThread(MainThread, started 4320629568)>]

  

2) 进程池并行异步执行:

  1. import threading #ProcessPoolExecutor进程池
  2. import logging
  3. from concurrent import futures
  4. import time
  5. logging.basicConfig(level=logging.INFO,format="%(thread)s %(message)s")
  6.  
  7. def work(n):
  8. logging.info('wokring-{}'.format(n))
  9. time.sleep(5)
  10. logging.info('end work-{}'.format(n))
  11.  
  12. if __name__ == "__main__":
  13. executor = futures.ProcessPoolExecutor(3) #进程
  14.  
  15. fs = []
  16.  
  17. for i in range(3):
  18. f = executor.submit(work,i)
  19. fs.append(f)
  20.  
  21. for i in range(3,6):
  22. f = executor.submit(work,i)
  23. fs.append(f)
  24.  
  25. while True:
  26. time.sleep(2)
  27. logging.info(threading.enumerate())
  28.  
  29. flag = True
  30.  
  31. for f in fs:
  32.  
  33. flag = flag and f.done()
  34.  
  35. if flag:
  36. executor.shutdown()
  37. logging.info(threading.enumerate())
  38. break
  39.  
  40. #运行结果:
  41. 4320629568 wokring-1
  42. 4320629568 wokring-2
  43. 4320629568 wokring-0
  44. 4320629568 [<_MainThread(MainThread, started 4320629568)>, <Thread(Thread-1, started daemon 123145319972864)>, <Thread(QueueFeederThread, started daemon 123145325228032)>]
  45. 4320629568 [<_MainThread(MainThread, started 4320629568)>, <Thread(Thread-1, started daemon 123145319972864)>, <Thread(QueueFeederThread, started daemon 123145325228032)>]
  46. 4320629568 end work-0
  47. 4320629568 end work-1
  48. 4320629568 end work-2
  49. 4320629568 wokring-3
  50. 4320629568 wokring-4
  51. 4320629568 wokring-5
  52. 4320629568 [<_MainThread(MainThread, started 4320629568)>, <Thread(Thread-1, started daemon 123145319972864)>, <Thread(QueueFeederThread, started daemon 123145325228032)>]
  53. 4320629568 [<_MainThread(MainThread, started 4320629568)>, <Thread(Thread-1, started daemon 123145319972864)>, <Thread(QueueFeederThread, started daemon 123145325228032)>]
  54. 4320629568 end work-3
  55. 4320629568 end work-4
  56. 4320629568 end work-5
  57. 4320629568 [<_MainThread(MainThread, started 4320629568)>, <Thread(Thread-1, started daemon 123145319972864)>, <Thread(QueueFeederThread, started daemon 123145325228032)>]
  58. 4320629568 [<_MainThread(MainThread, started 4320629568)>]

  

支持上下文管理

concurrent.futures.ProcessPoolExecutor继承自conncurrent.futures.base.Executor,而父类有__enter__、__exit__方法,支持上下文管理。可以使用with语句

  1. with ThreadPoolExecutor(max_workers=5) as executor:
  2. future = executor.submit(work,n)
  3. print(future.result())

  

总结:

统一了线程池、进程池调用,简化了编程。

是Python简单的思想哲学的体现。

唯一的缺点:无法设置线程名称。

[Python 多线程] Concurrent (十五)的更多相关文章

  1. Python进阶(三十五)-Fiddler命令行和HTTP断点调试

    Python进阶(三十五)-Fiddler命令行和HTTP断点调试 一. Fiddler内置命令   上一节(使用Fiddler进行抓包分析)中,介绍到,在web session(与我们通常所说的se ...

  2. “全栈2019”Java多线程第二十五章:生产者与消费者线程详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...

  3. “全栈2019”Java多线程第十五章:当后台线程遇到finally

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...

  4. 孤荷凌寒自学python第八十五天配置selenium并进行模拟浏览器操作1

    孤荷凌寒自学python第八十五天配置selenium并进行模拟浏览器操作1 (完整学习过程屏幕记录视频地址在文末) 要模拟进行浏览器操作,只用requests是不行的,因此今天了解到有专门的解决方案 ...

  5. 孤荷凌寒自学python第七十五天开始写Python的第一个爬虫5

    孤荷凌寒自学python第七十五天开始写Python的第一个爬虫5 (完整学习过程屏幕记录视频地址在文末) 今天在上一天的基础上继续完成对我的第一个代码程序的书写. 直接上代码.详细过程见文末屏幕录像 ...

  6. 孤荷凌寒自学python第六十五天学习mongoDB的基本操作并进行简单封装4

    孤荷凌寒自学python第六十五天学习mongoDB的基本操作并进行简单封装4 (完整学习过程屏幕记录视频地址在文末) 今天是学习mongoDB数据库的第十一天. 今天继续学习mongoDB的简单操作 ...

  7. 孤荷凌寒自学python第四十五天Python初学基础基本结束的下阶段预安装准备

     孤荷凌寒自学python第四十五天Python初学基础基本结束的下阶段预安装准备 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 今天本来应当继续学习Python的数据库操作,但根据过去我自 ...

  8. 孤荷凌寒自学python第三十五天python的文件操作之针对文件操作的os模块的相关内容

     孤荷凌寒自学python第三十五天python的文件操作之针对文件操作的os模块的相关内容 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 一.打开文件后,要务必记得关闭,所以一般的写法应当 ...

  9. 进击的Python【第十五章】:Web前端基础之DOM

    进击的Python[第十五章]:Web前端基础之DOM 简介:文档对象模型(Document Object Model,DOM)是一种用于HTML和XML文档的编程接口.它给文档提供了一种结构化的表示 ...

随机推荐

  1. Java相关脚本

    本人摘自:https://github.com/oldratlee/useful-scripts/blob/master/docs/java.md#beer-show-busy-java-thread ...

  2. 代码实现SpringMvc

    偶然看到一篇100多行实现SpringMvc的博客,阅读后整理加实现出来.大家共勉!(纸上得来终觉浅,绝知此事要躬行.) 实现Spring的部分. Bean工厂,统一创建Bean: IOC,实现Bea ...

  3. Windows的图形设备接口与Windows绘图

    本次学习目标 理解DC, 映像模式, 坐标系统, 窗口和视口; 学习获取绘图工具(画笔/画刷)的句柄, 设置颜色, 能定义映像模式; 会使用常用的绘图函数. 编写程序: 在屏幕上出现一个圆心沿正弦曲线 ...

  4. SDOI2017 树点涂色——LCT the END

    Description Bob有一棵n个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同.定义一条路 径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜色. ...

  5. Http Status Code 套餐合集(转载)

    1xx(临时响应) 表示临时响应并需要请求者继续执行操作的状态代码. 100(继续)请求者应当继续提出请求. 服务器返回此代码表示已收到请求的第一部分,正在等待其余部分. 101(切换协议)请求者已要 ...

  6. Canvas中的剪切clip()方法

    Canvas中的剪切 接下来我们要聊的不是图像的合成,而是Canvas中的另一个有用的功能:剪切区域.它是Canvas之中由路径所定义的一块区域,浏览器会将所有的绘图操作都限制在本区域内执行.在默认情 ...

  7. python模拟登陆豆瓣——简单方法

    学爬虫有一段时间了,前面没有总结又重装了系统,导致之前的代码和思考都没了..所以还是要及时整理总结备份.下面记录我模拟登陆豆瓣的方法,方法一登上了豆瓣,方法二重定向到了豆瓣中“我的喜欢”列表,获取了第 ...

  8. Android学习笔记(2)----LocationManager的使用

    今天使用Android的LocationManager制作了一款获取当前经纬坐标位置的软件. LocationManager获取的只是经纬坐标点,为了解析出当前经纬坐标点的实际位置,可以使用Googl ...

  9. Chromebook 阿里云ECS 配置 jupyter Notebook

    前言 新购入一台Chromebook Pixel ,为方便机器学习编程,用学生版的阿里云ECS搭建了jupyter Notebook 为减少下次踩坑,参考链接记录如下: 参考链接 阿里云使用笔记(一) ...

  10. qt 拖放dropEvent

    1.拖放操作分为两个截然不同的动作: 拖动和放下. 拖动通过 void dragEnterEvent(QDragEnterEvent * event); 来实现. 放下通过 void dropEven ...