Python之concurrent.futures模块的使用
concurrent.futures的作用:
管理并发任务池。concurrent.futures模块提供了使用工作线程或进程池运行任务的接口。线程和进程池API都是一样,所以应用只做最小的修改就可以在线程和进程之间地切换
1、基于线程池使用map()
#!/usr/bin/env python
# -*- coding: utf-8 -*- from concurrent import futures
import threading
import time def task(n):
print('{}: 睡眠 {}'.format(threading.current_thread().name,n))
time.sleep(n / 10)
print('{}: 执行完成 {}'.format(threading.current_thread().name,n))
return n / 10 ex = futures.ThreadPoolExecutor(max_workers=2)
print('main: 开始运行')
results = ex.map(task, range(5, 0, -1)) #返回值是generator 生成器
print('main: 未处理的结果 {}'.format(results))
print('main: 等待真实结果')
real_results = list(results)
print('main: 最终结果: {}'.format(real_results))
futures_thread_pool_map.py
运行效果
[root@ mnt]# python3 futures_thread_pool_map.py
main: 开始运行
ThreadPoolExecutor-0_0: 睡眠
ThreadPoolExecutor-0_1: 睡眠
main: 未处理的结果 <generator object Executor.map.<locals>.result_iterator at 0x7f1c97484678>
main: 等待真实结果
ThreadPoolExecutor-0_1: 执行完成
ThreadPoolExecutor-0_1: 睡眠
ThreadPoolExecutor-0_0: 执行完成
ThreadPoolExecutor-0_0: 睡眠
ThreadPoolExecutor-0_0: 执行完成
ThreadPoolExecutor-0_0: 睡眠
ThreadPoolExecutor-0_1: 执行完成
ThreadPoolExecutor-0_0: 执行完成
main: 最终结果: [0.5, 0.4, 0.3, 0.2, 0.1]
2、futures执行单个任务
#!/usr/bin/env python
# -*- coding: utf-8 -*- from concurrent import futures
import threading
import time def task(n):
print('{}: 睡眠 {}'.format(threading.current_thread().name, n))
time.sleep(n / 10)
print('{}: 执行完成 {}'.format(threading.current_thread().name, n))
return n / 10 ex = futures.ThreadPoolExecutor(max_workers=2)
print('main :开始')
f = ex.submit(task, 5)
print('main: future: {}'.format(f))
print('等待运行结果')
results = f.result()
print('main: result:{}'.format(results))
print('main: future 之后的结果:{}'.format(f))
futures_thread_pool_submit.py
运行效果
[root@ mnt]# python3 futures_thread_pool_submit.py
main :开始
ThreadPoolExecutor-0_0: 睡眠 5
main: future: <Future at 0x7f40c0a6a400 state=running>
等待运行结果
ThreadPoolExecutor-0_0: 执行完成 5
main: result:0.5
main: future 之后的结果:<Future at 0x7f40c0a6a400 state=finished returned float>
3、futures.as_completed()按任意顺序运行结果
#!/usr/bin/env python
# -*- coding: utf-8 -*- import random
import time
from concurrent import futures def task(n):
time.sleep(random.random())
return (n, n / 10) ex = futures.ThreadPoolExecutor(max_workers=2)
print('main: 开始')
wait_for = [
ex.submit(task, i) for i in range(5, 0, -1)
]
for f in futures.as_completed(wait_for):
print('main: result:{}'.format(f.result()))
futures_as_completed.py
运行效果
[root@ mnt]# python3 futures_as_completed.py
main: 开始
main: result:(, 0.5)
main: result:(, 0.4)
main: result:(, 0.3)
main: result:(, 0.1)
main: result:(, 0.2)
4、Future回调之futures.add_done_callback()
#!/usr/bin/env python
# -*- coding: utf-8 -*- from concurrent import futures
import time def task(n):
print('task {} : 睡眠'.format(n))
time.sleep(0.5)
print('task {} : 完成'.format(n))
return n / 10 def done(fn):
if fn.cancelled():
print('done {}:取消'.format(fn.arg))
elif fn.done():
error = fn.exception()
if error:
print('done {} : 错误返回 : {}'.format(fn.arg, error))
else:
result = fn.result()
print('done {} : 正常返回 : {}'.format(fn.arg, result)) if __name__ == '__main__':
ex = futures.ThreadPoolExecutor(max_workers=2)
print('main : 开始')
f = ex.submit(task, 5)
f.arg = 5
f.add_done_callback(done)
result = f.result()
futures_future_callback.py
运行效果
[root@ mnt]# python3 futures_future_callback.py
main : 开始
task : 睡眠
task : 完成
done : 正常返回 : 0.5
5、Future任务取消之futures.cancel()
#!/usr/bin/env python
# -*- coding: utf-8 -*- from concurrent import futures
import time def task(n):
print('task {} : 睡眠'.format(n))
time.sleep(0.5)
print('task {} : 完成'.format(n))
return n / 10 def done(fn):
if fn.cancelled():
print('done {}:取消'.format(fn.arg))
elif fn.done():
error = fn.exception()
if error:
print('done {} : 错误返回 : {}'.format(fn.arg, error))
else:
result = fn.result()
print('done {} : 正常返回 : {}'.format(fn.arg, result)) if __name__ == '__main__':
ex = futures.ThreadPoolExecutor(max_workers=2)
print('main : 开始')
tasks = [] for i in range(10, 0, -1):
print('main: submitting {}'.format(i))
f = ex.submit(task, i)
f.arg = i
f.add_done_callback(done)
tasks.append((i, f)) for i, task_obj in reversed(tasks):
if not task_obj.cancel():
print('main: 不能取消{}'.format(i)) ex.shutdown()
futures_future_callback_cancel.py
运行效果
[root@mnt]# python3 futures_future_callback_cancel.py
main : 开始
main: submitting
task : 睡眠
main: submitting
task : 睡眠
main: submitting
main: submitting
main: submitting
main: submitting
main: submitting
main: submitting
main: submitting
main: submitting
done :取消
done :取消
done :取消
done :取消
done :取消
done :取消
done :取消
done :取消
main: 不能取消9
main: 不能取消10
task : 完成
done : 正常返回 : 1.0
task : 完成
done : 正常返回 : 0.9
6、Future异常的处理
#!/usr/bin/env python
# -*- coding: utf-8 -*- from concurrent import futures def task(n):
print('{} : 开始'.format(n))
raise ValueError('这个值不太好 {}'.format(n)) ex = futures.ThreadPoolExecutor(max_workers=2)
print('main: 开始...') f = ex.submit(task, 5) error = f.exception()
print('main: error:{}'.format(error)) try:
result = f.result()
except ValueError as e:
print('访问结果值的异常 {}'.format(e))
futures_future_exception
运行效果
[root@mnt]# python3 futures_future_exception.py
main: 开始...
: 开始
main: error:这个值不太好
访问结果值的异常 这个值不太好
7、Future上下文管理即利用with打开futures.ThreadPoolExecutor()
#!/usr/bin/env python
# -*- coding: utf-8 -*- from concurrent import futures def task(n):
print(n) with futures.ThreadPoolExecutor(max_workers=2) as ex:
print('main: 开始')
ex.submit(task, 1)
ex.submit(task, 2)
ex.submit(task, 3)
ex.submit(task, 4)
print('main: 结束')
futures_context_manager.py
运行效果
[root@ mnt]# python3 futures_context_manager.py
main: 开始 main: 结束
8、基于进程池使用map()
#!/usr/bin/env python
# -*- coding: utf-8 -*- from concurrent import futures
import os def task(n):
return (n, os.getpid()) if __name__ == '__main__':
ex = futures.ProcessPoolExecutor(max_workers=2)
results = ex.map(task, range(50, 0, -1))
for n, pid in results:
print('task {} in 进程id {}'.format(n, pid))
futures_process_pool_map.py
运行效果
[root@ mnt]# python3 futures_process_pool_map.py
task in 进程id
task in 进程id
task in 进程id
task in 进程id
task in 进程id
9、基于进程池异常处理
#!/usr/bin/env python
# -*- coding: utf-8 -*- from concurrent import futures
import os
import signal def task(n):
return (n, os.getpid()) if __name__ == '__main__':
with futures.ProcessPoolExecutor(max_workers=2) as ex:
print('获取工作进程的id')
f1 = ex.submit(os.getpid)
pid1 = f1.result() print('结束进程 {}'.format(pid1))
os.kill(pid1, signal.SIGHUP) print('提交其它进程')
f2 = ex.submit(os.getpid)
try:
pid2 = f2.result()
except futures.process.BrokenProcessPool as e:
print('不能开始新的任务:{}'.format(e))
futures_process_pool_broken.py
运行效果
[root@ mnt]# python3 futures_process_pool_broken.py
获取工作进程的id
结束进程
提交其它进程
不能开始新的任务:A process in the process pool was terminated abruptly while the future was running or pending.
Python之concurrent.futures模块的使用的更多相关文章
- python之concurrent.futures模块
一.concurrent.futures模块简介 concurrent.futures 模块提供了并发执行调用的高级接口 并发可以使用threads执行,使用ThreadPoolExecutor 或 ...
- Python之线程 3 - 信号量、事件、线程队列与concurrent.futures模块
一 信号量 二 事件 三 条件Condition 四 定时器(了解) 五 线程队列 六 标准模块-concurrent.futures 基本方法 ThreadPoolExecutor的简单使用 Pro ...
- Python并发编程之线程池/进程池--concurrent.futures模块
一.关于concurrent.futures模块 Python标准库为我们提供了threading和multiprocessing模块编写相应的多线程/多进程代码,但是当项目达到一定的规模,频繁创建/ ...
- 《转载》Python并发编程之线程池/进程池--concurrent.futures模块
本文转载自Python并发编程之线程池/进程池--concurrent.futures模块 一.关于concurrent.futures模块 Python标准库为我们提供了threading和mult ...
- Python之路(第四十六篇)多种方法实现python线程池(threadpool模块\multiprocessing.dummy模块\concurrent.futures模块)
一.线程池 很久(python2.6)之前python没有官方的线程池模块,只有第三方的threadpool模块, 之后再python2.6加入了multiprocessing.dummy 作为可以使 ...
- Python之网络编程之concurrent.futures模块
需要注意一下不能无限的开进程,不能无限的开线程最常用的就是开进程池,开线程池.其中回调函数非常重要回调函数其实可以作为一种编程思想,谁好了谁就去掉 只要你用并发,就会有锁的问题,但是你不能一直去自己加 ...
- 45、concurrent.futures模块与协程
concurrent.futures —Launching parallel tasks concurrent.futures模块同时提供了进程池和线程池,它是将来的使用趋势,同样我们之前学习 ...
- 线程池、进程池(concurrent.futures模块)和协程
一.线程池 1.concurrent.futures模块 介绍 concurrent.futures模块提供了高度封装的异步调用接口 ThreadPoolExecutor:线程池,提供异步调用 Pro ...
- 35、concurrent.futures模块与协程
concurrent.futures —Launching parallel tasks concurrent.futures模块同时提供了进程池和线程池,它是将来的使用趋势,同样我们之前学习 ...
随机推荐
- win32多线程: 线程创建与结束等待
#include<Windows.h> #include<iostream> using namespace std; /*1.在启动一个线程之前,必须为线程编写一个全局的线程 ...
- one:arguments对象伪数组
这是我的第一个博客 <script> //计算N个数字的和 //定义一个函数,如果不确定用户是否传入了参数,或者说不知道用户传入了几个参数,没办法计算, // 但是如果在函数中知道了参数的 ...
- drf框架的模块分析
请求模块 请求模块是个什么鬼 ''' 1.drf的request是在wsgi的request基础上再次封装 2.wsgi的request作为drf的request一个属性:_request 3.新的r ...
- go 拼接sql
//原文链接:https://www.jianshu.com/p/a0569157c418 golang mysql拼接子查询 使用fmt.Sprintf拼接SQL 实例代码 func Select( ...
- Linux更改ext4根目录文件系统大小
首先通过lsblk 查看一下文件系统情况 然后通过fdisk /dev/sda类似命令,打开对应的磁盘管理,然后: 删除所有磁盘分区 重新建立一个更大的分区. 保存退出 再次通过lsblk查看分区大小 ...
- Java 反射理解(一)-- Class 类的使用
Java 反射理解(一)-- Class 类的使用 概念 这里阐述几个基本概念: 在面向对象的世界里,万事万物皆对象.(在 Java 语言中,静态的成员.普通数据类型除外) 类也是对象,类是 java ...
- Pycharm有必要改的几个默认设置项以及快捷键
最近在用Pycharm学习Python的时候,总有两个地方感觉不是很舒服,比如调用方法的时候区分大小写(thread就不会出现Thread,string就不会出现String)等,这让我稍稍有点不舒服 ...
- opencv ORB各参数的含义
ORB中有很多参数可以设置,在OpenCV中它可以通过ORB来创建一个ORB检测器. ORB::ORB(int nfeatures=500, float scaleFactor=1.2f, int n ...
- count(*),count(1),count(字段)
如果null参与聚集运算,则除count(*)之外其它聚集函数都忽略null. 如: ID DD 1 e 2 null select count( ...
- Shell-使用mkfifo实现多任务并发及并发数控制
以下为代码实现的一个模拟场景:3个生产者,在不断提供服务,处理需求,假设1s处理一个. 20个消费者,在不断消耗供给产品,提交需求,假设3s消耗一个. 情景分析:由于消费者的提交需求能力 和 生产者处 ...