[Python 多线程] Concurrent (十五)
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) 线程池并行异步执行:
# 并行异步执行,线程 ThreadPoolExecutor import threading
import logging
from concurrent import futures
import time
logging.basicConfig(level=logging.INFO,format="%(thread)s %(message)s") def work(n): #工作函数
logging.info('wokring-{}'.format(n))
time.sleep(5)
logging.info('end work-{}'.format(n)) executor = futures.ThreadPoolExecutor(3) #线程 fs = [] #线程池容器 for i in range(3):
f = executor.submit(work,i) #提交执行的函数及参数
fs.append(f) for i in range(3,6):
f = executor.submit(work,i)
fs.append(f) while True:
time.sleep(2)
logging.info(threading.enumerate()) flag = True for f in fs:
flag = flag and f.done() #调用是否被成功的取消或运行完成 if flag:
executor.shutdown() #清理池
logging.info(threading.enumerate())
break #运行结果:
123145331777536 wokring-0
123145337032704 wokring-1
123145342287872 wokring-2
4320629568 [<_MainThread(MainThread, started 4320629568)>, <Thread(Thread-1, started daemon 123145331777536)>, <Thread(Thread-2, started daemon 123145337032704)>, <Thread(Thread-3, started daemon 123145342287872)>]
4320629568 [<_MainThread(MainThread, started 4320629568)>, <Thread(Thread-1, started daemon 123145331777536)>, <Thread(Thread-2, started daemon 123145337032704)>, <Thread(Thread-3, started daemon 123145342287872)>]
123145331777536 end work-0
123145331777536 wokring-3
123145337032704 end work-1
123145337032704 wokring-4
123145342287872 end work-2
123145342287872 wokring-5
4320629568 [<_MainThread(MainThread, started 4320629568)>, <Thread(Thread-1, started daemon 123145331777536)>, <Thread(Thread-2, started daemon 123145337032704)>, <Thread(Thread-3, started daemon 123145342287872)>]
4320629568 [<_MainThread(MainThread, started 4320629568)>, <Thread(Thread-1, started daemon 123145331777536)>, <Thread(Thread-2, started daemon 123145337032704)>, <Thread(Thread-3, started daemon 123145342287872)>]
123145331777536 end work-3
123145342287872 end work-5
123145337032704 end work-4
4320629568 [<_MainThread(MainThread, started 4320629568)>, <Thread(Thread-1, started daemon 123145331777536)>, <Thread(Thread-2, started daemon 123145337032704)>, <Thread(Thread-3, started daemon 123145342287872)>]
4320629568 [<_MainThread(MainThread, started 4320629568)>]
2) 进程池并行异步执行:
import threading #ProcessPoolExecutor进程池
import logging
from concurrent import futures
import time
logging.basicConfig(level=logging.INFO,format="%(thread)s %(message)s") def work(n):
logging.info('wokring-{}'.format(n))
time.sleep(5)
logging.info('end work-{}'.format(n)) if __name__ == "__main__":
executor = futures.ProcessPoolExecutor(3) #进程 fs = [] for i in range(3):
f = executor.submit(work,i)
fs.append(f) for i in range(3,6):
f = executor.submit(work,i)
fs.append(f) while True:
time.sleep(2)
logging.info(threading.enumerate()) flag = True for f in fs: flag = flag and f.done() if flag:
executor.shutdown()
logging.info(threading.enumerate())
break #运行结果:
4320629568 wokring-1
4320629568 wokring-2
4320629568 wokring-0
4320629568 [<_MainThread(MainThread, started 4320629568)>, <Thread(Thread-1, started daemon 123145319972864)>, <Thread(QueueFeederThread, started daemon 123145325228032)>]
4320629568 [<_MainThread(MainThread, started 4320629568)>, <Thread(Thread-1, started daemon 123145319972864)>, <Thread(QueueFeederThread, started daemon 123145325228032)>]
4320629568 end work-0
4320629568 end work-1
4320629568 end work-2
4320629568 wokring-3
4320629568 wokring-4
4320629568 wokring-5
4320629568 [<_MainThread(MainThread, started 4320629568)>, <Thread(Thread-1, started daemon 123145319972864)>, <Thread(QueueFeederThread, started daemon 123145325228032)>]
4320629568 [<_MainThread(MainThread, started 4320629568)>, <Thread(Thread-1, started daemon 123145319972864)>, <Thread(QueueFeederThread, started daemon 123145325228032)>]
4320629568 end work-3
4320629568 end work-4
4320629568 end work-5
4320629568 [<_MainThread(MainThread, started 4320629568)>, <Thread(Thread-1, started daemon 123145319972864)>, <Thread(QueueFeederThread, started daemon 123145325228032)>]
4320629568 [<_MainThread(MainThread, started 4320629568)>]
支持上下文管理
concurrent.futures.ProcessPoolExecutor继承自conncurrent.futures.base.Executor,而父类有__enter__、__exit__方法,支持上下文管理。可以使用with语句
with ThreadPoolExecutor(max_workers=5) as executor:
future = executor.submit(work,n)
print(future.result())
总结:
统一了线程池、进程池调用,简化了编程。
是Python简单的思想哲学的体现。
唯一的缺点:无法设置线程名称。
[Python 多线程] Concurrent (十五)的更多相关文章
- Python进阶(三十五)-Fiddler命令行和HTTP断点调试
Python进阶(三十五)-Fiddler命令行和HTTP断点调试 一. Fiddler内置命令 上一节(使用Fiddler进行抓包分析)中,介绍到,在web session(与我们通常所说的se ...
- “全栈2019”Java多线程第二十五章:生产者与消费者线程详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...
- “全栈2019”Java多线程第十五章:当后台线程遇到finally
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...
- 孤荷凌寒自学python第八十五天配置selenium并进行模拟浏览器操作1
孤荷凌寒自学python第八十五天配置selenium并进行模拟浏览器操作1 (完整学习过程屏幕记录视频地址在文末) 要模拟进行浏览器操作,只用requests是不行的,因此今天了解到有专门的解决方案 ...
- 孤荷凌寒自学python第七十五天开始写Python的第一个爬虫5
孤荷凌寒自学python第七十五天开始写Python的第一个爬虫5 (完整学习过程屏幕记录视频地址在文末) 今天在上一天的基础上继续完成对我的第一个代码程序的书写. 直接上代码.详细过程见文末屏幕录像 ...
- 孤荷凌寒自学python第六十五天学习mongoDB的基本操作并进行简单封装4
孤荷凌寒自学python第六十五天学习mongoDB的基本操作并进行简单封装4 (完整学习过程屏幕记录视频地址在文末) 今天是学习mongoDB数据库的第十一天. 今天继续学习mongoDB的简单操作 ...
- 孤荷凌寒自学python第四十五天Python初学基础基本结束的下阶段预安装准备
孤荷凌寒自学python第四十五天Python初学基础基本结束的下阶段预安装准备 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 今天本来应当继续学习Python的数据库操作,但根据过去我自 ...
- 孤荷凌寒自学python第三十五天python的文件操作之针对文件操作的os模块的相关内容
孤荷凌寒自学python第三十五天python的文件操作之针对文件操作的os模块的相关内容 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 一.打开文件后,要务必记得关闭,所以一般的写法应当 ...
- 进击的Python【第十五章】:Web前端基础之DOM
进击的Python[第十五章]:Web前端基础之DOM 简介:文档对象模型(Document Object Model,DOM)是一种用于HTML和XML文档的编程接口.它给文档提供了一种结构化的表示 ...
随机推荐
- DButils分析
package com.ldf.utils; import java.sql.Connection; public class DBUtils { private static String driv ...
- golang label breaks
我们在for多层嵌套时,有时候需要直接跳出所有嵌套循环, 这时候就可以用到go的label breaks特征了. 先看一个范例代码: package main import ( "f ...
- libevent学习笔记 —— 牛刀小试:简易的服务器
回想起之前自己用纯c手动写epoll循环,libevent用起来还真是很快捷啊!重写了之前学习的时候的一个例子,分别用纯c与libevent来实现.嗯,为了方便对比一下,就一个文件写到黑了. 纯c版: ...
- Python Django 路由分发
mysite1 为一个django工程 cmdb为一个项目 dashboard为一个项目 在mysite1工程下的urls.py中定义如下: from django.conf.urls import ...
- 使用装饰器减少try ...finally的重复使用
@util.try_except_bskgk def added_user_handle(cur, search_time): added_user_sql = """ ...
- ES6学习笔记(五)-函数扩展
- bootstrap框架怎么在html页面加载使用
今天敲代码的时候,正好碰到这个问题. 与大家分享这个解决方法: 1/7 到bootstrap官方网站下载,对于我们开发者来说,直接下载编译和压缩后的CSS.JavaScript文件,另外还包含 ...
- 微信小程序-view组件
<view class="section"> <view class="section__title">flex-direction: ...
- css权威指南读书笔记-第10章浮动和定位
这一章看了之后真是豁然开朗,之前虽然写了圣杯布局和双飞翼布局,有些地方也是模糊的,现在打算总结之后再写一遍. 以下都是从<css权威指南>中摘抄的我认为很有用的说明. 浮动元素 一个元素浮 ...
- 【javascript】javascript设计模式mixin模式
概述: Mixin是JavaScript中用的最普遍的模式,几乎所有流行类库都会有Mixin的实现.任意一个对象的全部或部分属性拷贝到另一个对象上. 一 .混合对象 二 .混合类