#!/usr/bin/env python
# -*- coding: utf-8 -*-
import time
from concurrent import futures
'''
关键:
1、线程池提出原因:同时创建很多线程是需要消耗资源的,可以创建几个线程,其他任务在等待线程池中线程
完成,就可以继续处理
本质:将任务提交到线程池的任务队列中
组成:等待队列和一系列线程
作用: 主线程可以获取线程状态,返回值;一个线程完成,主线程可以知道
2、 concurrent.futures.Executor
作用:抽象类,有异步执行调用方法。有两个子类:
ThreadPoolExecutor(max_workers)和ProcessPoolExecutor(max_workers)
max_workers:表示有多少worker并行执行该任务,异步调用,若为None,则设置为机器的处理器数目
3、 Executor.submit(fn, *args, **kwargs)
作用:调度函数的执行
参数: fn: 异步执行的函数,*args: fn的参数,**kwargs: fn的参数
返回值: 返回一个Future对象,表示可调用的执行
注意: submit是立即返回的
4、 Executor.map(function, *iterables, timeout=None):
作用:将argument作为参数执行函数,以异步方式执行;相当于map(func, *iterables)
但是func是异步执行,如果操作超时,返回错误;不指定timeout,则不设置超时
参数: func:异步执行函数,*iterables:可迭代对象,如列表,每一次func执行,都会从iterables中取参数
5、 Executor.shutdown(wait=True)
作用:释放系统资源,在submit()或map()等异步操作之后调用,使用with语句可以避免显示调用该方法
6、 concurrent.futures.as_completed(fs, timeout=None)
作用:接收一个future列表,返回一个迭代器,在运行结束后删除future,一次取出所有任务的结果
本质:是生成器,任务还没有完成,会阻塞;先完成任务会先通知主线程
7 关于concurrent.futures.Future
concurrent.future: 未来完成的操作,异步编程
cancel():取消调用,若执行,不能取消;返回值表示是否可以取消
cancelled():返回是否已经取消
done():返回任务是否已经成功完成
result(timeout=None):返回调用的结果,如果还没有完成,将会等待一定时间
exception(timeout=None):返回调用的异常
wait(fs, timeout=None, return_when=ALL_COMPLETED):让主线程阻塞,直到满足设定的要求
参数:等待的任务序列,超时时间,等待条件。ALL_COMPLETED表示要等待所有任务完成。
总结:
进程池:不受GIL全局解释器锁的限制,缩短执行时间,使用多核处理的模块,推荐使用
线程池:不管多少处理器,运行的时候只有一个线程运行。【协程:多个线程之间互相渡让cpu的控制权】
线程池/进程池 适用:处理多个客户端请求的服务端部分
参考:
[1] https://www.jianshu.com/p/b9b3d66aa0be
[2] http://lovesoo.org/analysis-of-asynchronous-concurrent-python-module-concurrent-futures.html
[3] https://python-parallel-programmning-cookbook.readthedocs.io/zh_CN/latest/chapter4/02_Using_the_concurrent.futures_Python_modules.html
[4] https://docs.python.org/3/library/concurrent.futures.html
[5] https://docs.python.org/3/library/concurrent.futures.html
'''
def run(num):
time.sleep(num)
return num
def threadPoolExecutor_submit():
with futures.ThreadPoolExecutor(max_workers=1) as executor:
future = executor.submit(run, 1)
result = future.result()
print result
def threadPoolExecutorMap():
data = [1, 2, 3]
with futures.ThreadPoolExecutor(max_workers=1) as executor:
results = list(executor.map(run, data))
return results
def process():
results = threadPoolExecutorMap()
print results
if __name__ == "__main__":
process()