python因为其全局解释器锁GIL而无法通过线程实现真正的平行计算。这个论断我们不展开,但是有个概念我们要说明,IO密集型 vs. 计算密集型。

IO密集型:读取文件,读取网络套接字频繁。

计算密集型:大量消耗CPU的数学与逻辑运算,也就是我们这里说的平行计算。

而concurrent.futures模块,可以利用multiprocessing实现真正的平行计算。

核心原理是:concurrent.futures会以子进程的形式,平行的运行多个python解释器,从而令python程序可以利用多核CPU来提升执行速度。由于子进程与主解释器相分离,所以他们的全局解释器锁也是相互独立的。每个子进程都能够完整的使用一个CPU内核。

一、初体验

Future总结

1. python3自带,python2需要安装
2. Executer对象
它是一个抽象类,它提供了异步执行的方法,他不能直接使用,但可以通过它的子类
ThreadPoolExecuter和ProcessPoolExecuter
2.1 Executer.submit(fn,*args,**kwargs)
fn:需要异步执行的函数
*args,**kwargs fn接受的参数
该方法的作用就是提交一个可执行的回调task,它返回一个Future对象
2.2 map(fn,*iterables, timeout=None, chunksize=1)
map(task,URLS) # 返回一个map()迭代器,这个迭代器中的回调执行返回的结果是有序的 3. Future对象相关
future可以理解为一个在未来完成的操作,这是异步编程的基础
通常情况下我们在遇到IO操作的时候,将会发生阻塞,cpu不能做其他事情
而future的引入帮助我们在这段等待时间可以完成其他的操作
3.1 done():
如果当前线程已取消/已成功,返回True。
3.2 cance():
如果当前线程正在执行,并且不能取消调用,返回Flase。否则调用取消,返回True 3.3 running():
如果当前的线程正在执行,则返回True
3.4 result():
返回调用返回的值,如果调用尚未完成,则此方法等待
如果等待超时,会抛出concurrent.futures.TimeoutError
如果没有指定超时时间,则等待无时间限制
如果在完成之前,取消了Future,则会引发CancelledError 4. as_completed():
在多个Future实例上的迭代器将会被返回
这些Future实例由fs完成时产生。
由fs返回的任何重复的Future,都会被返回一次。
里面保存的都是已经执行完成的Future对象 5. wait():
返回一个元祖,元祖包含两个元素
1. 已完成的future集合
2. 未完成的future集合

初体验

# coding=utf-8
from concurrent import futures
from concurrent.futures import Future
import time def return_future(msg):
time.sleep(3)
return msg pool = futures.ThreadPoolExecutor(max_workers=2) t1 = pool.submit(return_future,'hello')
t2 = pool.submit(return_future,'world') time.sleep(3)
print(t1.done()) # 如果顺利完成,则返回True
time.sleep(3)
print(t2.done()) print(t1.result()) # 获取future的返回值
time.sleep(3)
print(t2.result()) print("主线程")

mapfunc* iterablestimeout = Nonechunksize = 1 

# coding=utf-8

import time
from concurrent.futures import Future,as_completed
from concurrent.futures import ThreadPoolExecutor as Pool
import requests
import time URLS = ['http://www.baidu.com', 'http://qq.com', 'http://sina.com'] def task(url,timeout=10):
return requests.get(url=url,timeout=timeout) pool = Pool()
result = pool.map(task,URLS) start_time = time.time()
# 按照URLS的顺序返回
for res in result:
print("{} {}".format(res.url,len(res.content))) # 无序的
with Pool(max_workers=3) as executer:
future_task = [executer.submit(task,url) for url in URLS] for f in as_completed(future_task):
if f.done():
f_ret = f.result() # f.result()得到task的返回值,requests对象
print('%s, done, result: %s, %s' % (str(f), f_ret.url, len(f_ret.content))) print("耗时",time.time() - start_time)
print("主线程")

二、Future对象

Future可以理解为一个未来完成的操作
当我们执行io操作的时候,在等待返回结果之前会产生阻塞
cpu不能做其他事情,而Future的引入帮助我们在等待的这段时间可以完成其他操作

from concurrent.futures import ThreadPoolExecutor as Pool
from concurrent.futures import as_completed
import requests
import time URLS = ['http://www.baidu.com', 'http://qq.com', 'http://sina.com'] def task(url,timeout=10):
return requests.get(url=url,timeout=timeout) # start_time = time.time()
# for url in URLS:
# ret = task(url)
# print("{} {}".format(ret.url,len(ret.content)))
# print("耗时",time.time() - start_time)
with Pool(max_workers=3) as executor:
# 创建future任务
future_task = [executor.submit(task,url) for url in URLS] for f in future_task:
if f.running():
print("%s is running"%str(f)) for f in as_completed(future_task):
try:
ret = f.done()
if ret:
f_ret = f.result()
print('%s, done, result: %s, %s' % (str(f), f_ret.url, len(f_ret.content)))
except Exception as e:
f.cance()
print(e) """
url不是按照顺序返回的,说明并发时,当访问某一个url时,如果没有得到返回结果,不会发生阻塞
<Future at 0x1c63990e6d8 state=running> is running
<Future at 0x1c639922780 state=running> is running
<Future at 0x1c639922d30 state=running> is running
<Future at 0x1c63990e6d8 state=finished returned Response>, done, result: http://www.baidu.com/, 2381
<Future at 0x1c639922780 state=finished returned Response>, done, result: https://www.qq.com?fromdefault, 243101
<Future at 0x1c639922d30 state=finished returned Response>, done, result: http://sina.com/, 23103
"""

三、模块方法

concurrent.futures.wait(fstimeout=Nonereturn_when=ALL_COMPLETED)

wait()会返回一个tuple,
tuple会包含两个集合
1. 已完成的集合
2. 未完成的集合
使用wait()会获得更大的自由度,他接受三个参数
FIRST_COMPLETED, FIRST_EXCEPTION和ALL_COMPLETE
默认为ALL_COMPLETE
from concurrent.futures import Future
from concurrent.futures import ThreadPoolExecutor as Pool
from concurrent.futures import as_completed,wait
import requests URLS = ['http://www.baidu.com', 'http://qq.com', 'http://sina.com'] def task(url,timeout=10):
return requests.get(url=url,timeout=timeout) with Pool(max_workers=3) as execute :
fulture_task = [execute.submit(task,url) for url in URLS] for f in fulture_task:
if f.running():
print("%s"%(str(f))) """
并且wait还有timeout和return_when两个参数
return_when有三个常量
FIRST_COMPLETED 任何一个future_task执行完成时/取消时,改函数返回
FIRST_EXCEPTION 任何一个future_task发生异常时,该函数返回,如果没有异常发生,等同于ALL_COMPLETED
ALL_COMPLETED 当所有的future_task执行完毕返回
"""
results = wait(fulture_task,return_when="FIRST_COMPLETED")#
done = results[0]
for d in done:
print(d)

concurrent.futures.as_completed(fstimeout=None)

在多个Future实例上的迭代器将会被返回
这些Future实例由fs完成时产生。
由fs返回的任何重复的Future,都会被返回一次。
里面保存的都是已经执行完成的Future对象
from concurrent.futures import ThreadPoolExecutor as Pool
from concurrent.futures import as_completed
import requests
import time URLS = ['http://www.baidu.com', 'http://qq.com', 'http://sina.com'] def task(url,timeout=10):
return requests.get(url=url,timeout=timeout) with Pool(max_workers=3) as executor:
# 创建future任务
future_task = [executor.submit(task,url) for url in URLS] for f in future_task:
if f.running():
print("%s is running"%str(f)) for f in as_completed(future_task):
try:
ret = f.done()
if ret:
f_ret = f.result()
print('%s, done, result: %s, %s' % (str(f), f_ret.url, len(f_ret.content)))
except Exception as e:
f.cance()
print(e)

concurrent.futures- 启动并行任务的更多相关文章

  1. python concurrent.futures

    python因为其全局解释器锁GIL而无法通过线程实现真正的平行计算.这个论断我们不展开,但是有个概念我们要说明,IO密集型 vs. 计算密集型. IO密集型:读取文件,读取网络套接字频繁. 计算密集 ...

  2. Thread类的其他方法,同步锁,死锁与递归锁,信号量,事件,条件,定时器,队列,Python标准模块--concurrent.futures

    参考博客: https://www.cnblogs.com/xiao987334176/p/9046028.html 线程简述 什么是线程?线程是cpu调度的最小单位进程是资源分配的最小单位 进程和线 ...

  3. 线程池、进程池(concurrent.futures模块)和协程

    一.线程池 1.concurrent.futures模块 介绍 concurrent.futures模块提供了高度封装的异步调用接口 ThreadPoolExecutor:线程池,提供异步调用 Pro ...

  4. python 全栈开发,Day42(Thread类的其他方法,同步锁,死锁与递归锁,信号量,事件,条件,定时器,队列,Python标准模块--concurrent.futures)

    昨日内容回顾 线程什么是线程?线程是cpu调度的最小单位进程是资源分配的最小单位 进程和线程是什么关系? 线程是在进程中的 一个执行单位 多进程 本质上开启的这个进程里就有一个线程 多线程 单纯的在当 ...

  5. python3 线程池-threadpool模块与concurrent.futures模块

    多种方法实现 python 线程池 一. 既然多线程可以缩短程序运行时间,那么,是不是线程数量越多越好呢? 显然,并不是,每一个线程的从生成到消亡也是需要时间和资源的,太多的线程会占用过多的系统资源( ...

  6. Python开发【笔记】:concurrent.futures 平行运算

    平行运算 前言: 编写Python程序时,我们可能会遭遇性能问题,即使优化了代码,程序也依然有可能运行的很慢,从而无法满足我们对执行速度的要求,目前的计算机,其cpu核心数越来越多,于是,我们可以考虑 ...

  7. 网络编程基础--多线程---concurrent.futures 模块---事件Event---信号量Semaphore---定时器Timer---死锁现象 递归锁----线程队列queue

    1 concurrent.futures 模块: # from abc import abstractmethod,ABCMeta # # class A(metaclass=ABCMeta): # ...

  8. Python之路(第四十六篇)多种方法实现python线程池(threadpool模块\multiprocessing.dummy模块\concurrent.futures模块)

    一.线程池 很久(python2.6)之前python没有官方的线程池模块,只有第三方的threadpool模块, 之后再python2.6加入了multiprocessing.dummy 作为可以使 ...

  9. concurrent.futures模块简单介绍(线程池,进程池)

    一.基类Executor Executor类是ThreadPoolExecutor 和ProcessPoolExecutor 的基类.它为我们提供了如下方法: submit(fn, *args, ** ...

  10. python全栈开发,Day42(Thread类的其他方法,同步锁,死锁与递归锁,信号量,事件,条件,定时器,队列,Python标准模块--concurrent.futures)

    昨日内容回顾 线程 什么是线程? 线程是cpu调度的最小单位 进程是资源分配的最小单位 进程和线程是什么关系? 线程是在进程中的一个执行单位 多进程 本质上开启的这个进程里就有一个线程 多线程 单纯的 ...

随机推荐

  1. tjoi2018D2T2(luogu4590) 游园会 (状压dp)

    题解劝退系列 设长的那个串是A,短的那个串是B. 那我们在如果已经知道某个A的时候,A[1..i]和B[1..j]的最长公共子序列$f[i][j]=max\{f[i-1][j],f[i][j-1],f ...

  2. 【bzoj4818】 Sdoi2017—序列计数

    http://www.lydsy.com/JudgeOnline/problem.php?id=4818 (题目链接) 题意 一个长度为$n$的序列,每个元素是不超过$m$的正整数,且这$n$个数的和 ...

  3. JavaScript的面向对象原理之原型链详解

    一.引言 在16年的10月份,在校内双选会找前端实习的时候,hr问了一个问题:JavaScript的面向对象理解吗?我张口就说“JavaScript是基于原型的!”.然后就没什么好说的了,hr可能不知 ...

  4. 获取EasyUI的treegrid的checkbox所有已勾选的数据

    EasyUI为TreeGrid的已勾选节点,未勾选节点,只勾选部分子节点的父节点分别添加了三个不同的样式,如下:样式一:tree-checkbox2 有子节点被选中样式二:tree-checkbox1 ...

  5. (大数 万进制) N! hdu1042

    N! Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Total Subm ...

  6. 部署高可用keepalived组件

    本文档讲解使用 keepalived 和 haproxy 实现 kube-apiserver 高可用的步骤: keepalived 提供 kube-apiserver 对外服务的 VIP: hapro ...

  7. sudALSA lib dlmisc.c:236:(snd1_dlobj_cache_get) Cannot open shared library /usr/lib/alsa-lib/libasound_module_pcm_pulse.so

    我使用的系统是kali,默认的浏览器为iceweasel.默认的浏览器很好用!! 但是,给浏览器安装flash后,播放视频,会报错:有视频,无声音. 下面给出我的解决方案:

  8. my phone blackberry classic / passport / priv / keyone

    smy blackberry classic PIN: 2BF66A72 / 查看手机位置https://protect.blackberry.com/protect/mydevice#BlackBe ...

  9. 附录B. Spring Boot 配置文件application.properties

    #SPRING CONFIG (ConfigFileApplicationListener) spring.config.name= # config file name (default to 'a ...

  10. C#常用的正则工具类写法

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...