使用concurrent.futures模块中的线程池与进程池
使用concurrent.futures模块中的线程池与进程池
线程池与进程池
以线程池举例,系统使用多线程方式运行时,会产生大量的线程创建与销毁,创建与销毁必定会带来一定的消耗,甚至导致系统资源的崩溃,这时使用线程池就是一个很好的解决方式。
“池”就说明了这里边维护了不止一个线程,线程池会提前创建好规定数量的线程,把需要使用多线程的任务提交给线程池,线程池会自己选择空闲的线程来执行提交的任务,任务完成后,线程并不会在池子中销毁,而是继续存在并等待完成下一个分配的任务。当线程池以满的时候,提交的线程会等待,也就是说线程池会有一个最大数量的运行线程限制。
进程池同样也是这个道理。
concurrent.futures模块为我们提供了ThreadPoolExecutor与ProcessPoolExecutor来使用线程进程池
ThreadPoolExecutor
下面是一个简单的例子
from concurrent.futures import ThreadPoolExecutor
import requests,time
url_list = ['https://www.cnblogs.com/', 'https://www.csdn.net/', 'https://github.com/']
def get_url(url):
content = requests.get(url).content.decode()
print(url+'已获取')
pool = ThreadPoolExecutor(max_workers=3)
start = time.time()
for url in url_list:
future = pool.submit(get_url,url)
# print(future)
end = time.time()
print(end-start)
输出的结果为:
0.0016434192657470703
https://www.cnblogs.com/已获取
https://www.csdn.net/已获取
https://github.com/已获取
例子中max_workers为指定线程个数,pool.submit为提交任务到线程执行,get_url为方法,url为参数
并且通过输出顺序可以看到线程池的执行并不会阻塞主线程的运行
print(future)被打了注释,现在我们取消注释运行一下:
Future at 0x7ff6cfaa8860 state=running
Future at 0x7ff6ce965860 state=running
Future at 0x7ff6ce96e278 state=running
0.006175518035888672
https://www.cnblogs.com/已获取
https://www.csdn.net/已获取
https://github.com/已获取
每提交一个任务后都会返回一个future对象,通过它可以查看任务运行的状态,state=running表示正在运行
future对象还有许多方法:
future.done()
from concurrent.futures import ThreadPoolExecutor
import requests,time
url_list = ['https://www.cnblogs.com/', 'https://www.csdn.net/', 'https://github.com/']
def get_url(url):
content = requests.get(url).content.decode()
print(url+'已获取')
pool = ThreadPoolExecutor(max_workers=3)
future_list = []
start = time.time()
for url in url_list:
future = pool.submit(get_url,url)
print(future.done())
future_list.append(future)
end = time.time()
print(end-start)
time.sleep(5)
for future in future_list:
print(future.done())
这里添加了future_list,为了显示效果中间添加sleep,最后结果为:
False
False
False
0.001546621322631836
https://www.cnblogs.com/已获取
https://www.csdn.net/已获取
https://github.com/已获取
True
True
True
future.done()可以显示当前允许状态
future.result()
from concurrent.futures import ThreadPoolExecutor
import requests,time
url_list = ['https://www.cnblogs.com/', 'https://www.csdn.net/', 'https://github.com/']
def get_url(url):
content = requests.get(url).content.decode()
print(url+'已获取')
return url
pool = ThreadPoolExecutor(max_workers=3)
future_list = []
start = time.time()
for url in url_list:
future = pool.submit(get_url,url)
print(future.result())
future_list.append(future)
end = time.time()
print(end-start)
for future in future_list:
print(future.result())
结果为:
https://www.cnblogs.com/已获取
https://www.cnblogs.com/
https://www.csdn.net/已获取
https://www.csdn.net/
https://github.com/已获取
https://github.com/
2.0975613594055176
https://www.cnblogs.com/
https://www.csdn.net/
https://github.com/
可见result()方法可以得到任务的返回值,但会阻塞,因为不运行完怎么会得到返回值呢?
除此之外还有很多方法:
使用map方法
from concurrent.futures import ThreadPoolExecutor
import requests,time
url_list = ['https://www.cnblogs.com/', 'https://www.csdn.net/', 'https://github.com/']
def get_url(url):
content = requests.get(url).content.decode()
print(url+'已获取')
return url
pool = ThreadPoolExecutor(max_workers=3)
pool.map(get_url,url_list)
与内建函数用法类似
使用wait方法
from concurrent.futures import ThreadPoolExecutor,wait
import requests,time
url_list = ['https://www.cnblogs.com/', 'https://www.csdn.net/', 'https://github.com/']
def get_url(url):
content = requests.get(url).content.decode()
print(url+'已获取')
return url
pool = ThreadPoolExecutor(max_workers=3)
future_list = []
start = time.time()
for url in url_list:
future = pool.submit(get_url,url)
future_list.append(future)
print(wait(future_list))
end = time.time()
print(end-start)
https://www.cnblogs.com/已获取
https://www.csdn.net/已获取
https://github.com/已获取
DoneAndNotDoneFutures(done={Future at 0x7f7506447da0 state=finished returned str, Future at 0x7f75074c9828 state=finished returned str, Future at 0x7f75064477f0 state=finished returned str}, not_done=set())6.678021430969238
wait返回值是一个元组,元组里是已完成和未完成的两个集合,它的return_when参数接受3个选项FIRST_COMPLETED, FIRST_EXCEPTION 和ALL_COMPLETE,默认是ALL_COMPLETE,意味着所有都完成,FIRST_COMPLETED意味着有一个完成了就可以了, FIRST_EXCEPTION是第一个出现异常就会停止wait
例如:
from concurrent.futures import ThreadPoolExecutor,wait
import requests,time
url_list = ['https://www.cnblogs.com/', 'https://www.csdn.net/', 'https://github.com/']
def get_url(url):
content = requests.get(url).content.decode()
print(url+'已获取')
return url
def error(url):
gg
pool = ThreadPoolExecutor(max_workers=4)
future_list = []
start = time.time()
future_list.append(pool.submit(error,'https://www.cnblogs.com/'))
for url in url_list:
future = pool.submit(get_url,url)
future_list.append(future)
print(wait(future_list,return_when='FIRST_EXCEPTION'))
end = time.time()
print(end-start)
DoneAndNotDoneFutures(done={Future at 0x7fd1a5b95320 state=finished raised NameError}, not_done={Future at 0x7fd1a4b11a90 state=running, Future at 0x7fd1a4b11a20 state=running, Future at 0x7fd1a4c897f0 state=running})
0.001996755599975586
https://www.cnblogs.com/已获取
https://www.csdn.net/已获取
https://github.com/已获取
ProcessPoolExecutor
进程池与线程池的使用方式基本相同,套用即可
使用concurrent.futures模块中的线程池与进程池的更多相关文章
- concurrent.futures模块(进程池&线程池)
1.线程池的概念 由于python中的GIL导致每个进程一次只能运行一个线程,在I/O密集型的操作中可以开启多线程,但是在使用多线程处理任务时候,不是线程越多越好,因为在线程切换的时候,需要切换上下文 ...
- 线程与进程 concurrent.futures模块
https://docs.python.org/3/library/concurrent.futures.html 17.4.1 Executor Objects class concurrent.f ...
- 线程池、进程池(concurrent.futures模块)和协程
一.线程池 1.concurrent.futures模块 介绍 concurrent.futures模块提供了高度封装的异步调用接口 ThreadPoolExecutor:线程池,提供异步调用 Pro ...
- concurrent.futures模块(进程池/线程池)
需要注意一下不能无限的开进程,不能无限的开线程最常用的就是开进程池,开线程池.其中回调函数非常重要回调函数其实可以作为一种编程思想,谁好了谁就去掉 只要你用并发,就会有锁的问题,但是你不能一直去自己加 ...
- Python并发编程之线程池/进程池--concurrent.futures模块
一.关于concurrent.futures模块 Python标准库为我们提供了threading和multiprocessing模块编写相应的多线程/多进程代码,但是当项目达到一定的规模,频繁创建/ ...
- python3 线程池-threadpool模块与concurrent.futures模块
多种方法实现 python 线程池 一. 既然多线程可以缩短程序运行时间,那么,是不是线程数量越多越好呢? 显然,并不是,每一个线程的从生成到消亡也是需要时间和资源的,太多的线程会占用过多的系统资源( ...
- 《转载》Python并发编程之线程池/进程池--concurrent.futures模块
本文转载自Python并发编程之线程池/进程池--concurrent.futures模块 一.关于concurrent.futures模块 Python标准库为我们提供了threading和mult ...
- 使用concurrent.futures模块并发,实现进程池、线程池
Python标准库为我们提供了threading和multiprocessing模块编写相应的异步多线程/多进程代码 从Python3.2开始,标准库为我们提供了concurrent.futures模 ...
- Python之路(第四十六篇)多种方法实现python线程池(threadpool模块\multiprocessing.dummy模块\concurrent.futures模块)
一.线程池 很久(python2.6)之前python没有官方的线程池模块,只有第三方的threadpool模块, 之后再python2.6加入了multiprocessing.dummy 作为可以使 ...
随机推荐
- Java——String对象
前言 实际上任何语言都没有提供字符串这个概念,而是使用字符数组来描述字符串.Java里面严格来说也是没有字符串的,在所有的开发里面字符串的应用有很多,于是Java为了应对便创建了String类这个字符 ...
- 为什么使用SLF4J比使用log4j或者java.util.logging更好
1.SLF4j是什么? SLF4J 并没有真正地实现日志记录,它只是一个允许你使用任何java日志记录库的抽象适配层. 如果你正在编写内部或者外部使用的API或者应用库的话,如果使用了slf4j,那么 ...
- React Native 入门基础知识总结
中秋在家闲得无事,想着做点啥,后来想想,为啥不学学 react native.在学习 React Native 时, 需要对前端(HTML,CSS,JavaScript)知识有所了解.对于JS,可以看 ...
- iOS SQLite详解
这周比较忙,前几天都加班到11点左右,基本都是到家都是12点左右(稍稍的抱怨一下,免费加班,何为免费,就是任何补偿都没有,例如调休,加班薪,餐补等各项福利,是一点都没有呀)因为App要上线了!App上 ...
- 编译部署mysql5.7.13
署环境centos7.2+mysql5.7.131.依赖包注: 相关依赖包的作用cmake:由于从 MySQL5.5 版本开始弃用了常规的 configure 编译方法,所以需要 CMake 编译器, ...
- C#常量和字段以及各种方法的语法总结
目录 一. 常量和字段.... 1 1. 常量.... 1 2.字段.... 1 二.方法.... 2 1.实例构造器和类(引用类型).... 2 2.实例构造器和结构(值类型).... 2 3.类型 ...
- 慕课网maven多环境配置
profile 下面的节点,是把profile 标签内容复制几份,并且需要把<activation> 去掉.在idea右侧 maven button 中会出现选择 节点. 接着打包命令和打 ...
- python基础学习(六)函数基础
函数的基本使用 函数的定义 def 函数名(): 函数封装的代码 …… def 是英文 define 的缩写 函数名称 应该能够表达 函数封装代码 的功能,方便后续的调用 函数名称 的命名应该 符合 ...
- 《Unix网络编程》读书笔记
UDP和TCP UDP(User Datagram Protocol,用户数据报协议)是一个无连接协议,不保证UDP数据报会到达其最终目的地,不保证各数据报的先后顺序跨网络后保持不变,也不保证每个数据 ...
- js 1.变量提升 2.条件语句 3.循环语句 4.加号+的使用
1.变量提升 变量提升是浏览器的一个功能,在运行js 代码执行前,浏览器会给js一个全局作用域叫 window,window 分两个模块,一个叫运营模块,内存模块找到当前作用域下的所有带var和fun ...