concurrent.futures
concurrent.futures是python3内置模块,用于并发。
ThreadPoolExecutor
先看下面例子:
import time
from concurrent import futures
def test(i):
time.sleep(1)
print("i:%d" % i)
start = time.time()
with futures.ThreadPoolExecutor(4) as ex:
r = ex.map(test, list(range(8)))
print(list(r))
print(time.time()-start)
输出结果:
i:0
i:3
i:2
i:1
i:4
i:7
i:6
i:5
[None, None, None, None, None, None, None, None]
2.0052473545074463
很明显,若用单线程,执行时间应该是8s,这里开了4个线程,执行时间只用了2s。
- ThreadPoolExecutor中参数表示线程的个数
- map方法返回一个生成器,获取各个函数的返回值
下面再看一个例子
import time
from concurrent import futures
def test(i):
time.sleep(1)
print("i:%d" % i)
return i
start = time.time()
with futures.ThreadPoolExecutor(4) as ex:
to_do=[]
for i in range(8):
future = ex.submit(test, i)
to_do.append(future)
for future in futures.as_completed(to_do):
print(future.result())
print(time.time()-start)
输出结果:
i:2
i:3
i:1
i:0
2
1
3
0
i:7
i:4
i:5
7
i:6
4
5
6
2.017911672592163
- submit方法的参数是一个可调用的对象,调用这个方法后会返回一个future。不阻塞。
- as_completed会等test结束后才会返回
- 因此future.result()直接获取到future的最终结果,无阻塞
ProcessPoolExecutor
由于pythonGIL的存在,使得同一时刻只会有一个CPU工作,对于CPU密集型,多线程无法发挥多CPU的优势,这个时候可以使用ProcessPoolExecutor 多进程,使用方法和ThreadPoolExecutor类似。
当然,concurrent中的并发不是很灵活,如果想要更灵活的使用多线程多进程,可以使用 threading和multiprocessing 模块。
网友评论