concurrent.futures调研

concurrent.futures调研

参考链接:

官网:https://docs.python.org/3.7/library/concurrent.futures.html

https://learnku.com/docs/pymotw/concurrentfutures-manage-pools-of-concurrent-tasks/3424#48d590

https://www.cnblogs.com/kangoroo/p/7628092.html

英文:https://pythonhosted.org/futures/

 

一、执行器

导入:  from concurrent.futures import ThreadPoolExecutor, wait, ProcessPoolExecutor

 

任务Executor是一个抽象类,由ThreadPoolExecutor和ProcessPoolExecutor返回,表示线程池和进程池。 两者的 API t 相同,所以我们只需要进行少量修改即可在线程与进程间切换。提供了如下方法submit,map,shutdown。值得一提的是Executor实现了__enter__和__exit__使得其对象可以使用with操作符。

 

先定义两个任务函数:

def task(arg):
    time.sleep(arg)
    print(f'收到了{arg}')
    return arg


def task1(arg):
    _ = [i for i in range(10 ** 7)]
    return arg
使用过程:

map()

exe = ThreadPoolExecutor(max_workers=2)
# 或者
exe = ProcessPoolExecutor(max_workers=2)
result_l = exe.map(task1, [2, 1, 3])

# print(result_l)  
# <generator object Executor.map.<locals>.result_iterator at 0x7f50f1ae9258>print(list(result_l))
print(list(result_l))
# [2, 1, 3]

 

map() 所返回的值实际上是一个特殊的迭代器,它被主程序迭代时会等待其中的并发任务返回,没返回就一直等待map() 返回的结果却总以执行顺序有关,使用 map() 可以以原本的顺序访问多个任务的返回值。

 

除了使用 map() ,我们还可以用 submit() 来执行单个任务 ,也是使用的 Future 实例等待任务结果的返回。

submit()

def main2():
    exe = ThreadPoolExecutor(max_workers=2)
    r1 = exe.submit(task, 2)
    r2 = exe.submit(task, 1)
    r3 = exe.submit(task, 3)
    print(r1.result(), r2.result(), r3.result())
# 运行结果
'''
收到了1
收到了2
收到了3
2 1 3'''


shutdown(self, wait=True)

释放资源,关闭执行器,关闭之后不能在添加任务。

二、模块函数: as_completed 和 wait

as_completed(fs, timeout=None)

参数:

fs 是包含future对象的序列

timeout 是最大等待时间, 单位秒,默认死等

返回:

包含future结果的迭代器, 如果future重复, 返回一次

as_completed() 返回结果与顺序无关,在某任务执行完成后立即进行处理

使用:
 

def main3():
    exe = ThreadPoolExecutor(max_workers=2)

    l = [exe.submit(task, i) for i in [2, 1, 3]]

    print([f.result() for f in as_completed(l)])

    '''
    收到了1
    收到了2
    收到了3
    [1, 2, 3] 
    不是map()按顺序执行的的[2, 1, 3]
    '''

wait(fs, timeout=None, return_when=ALL_COMPLETED)

参数:

前两个参数和as_completed一样,

fs 是包含future对象的序列

timeout 是最大等待时间,单位秒,默认死等
           FIRST_COMPLETED - 当任何一个future结束或取消

           FIRST_EXCEPTION - 当任何一个future抛出异常时返回.如果没有抛出异常,效果和ALL_COMPLETED一样.

           ALL_COMPLETED -   所有任务结束或取消时返回。

返回:

wait方法接会返回一个tuple(元组),tuple中包含两个set(集合),第一个是wait等待时间之前已完成的的future的集合(包含结束或取消),另外一个是未完成的的future的集合。

使用wait方法的一个优势就是获得更大的自由度,它接收三个参数FIRST_COMPLETED, FIRST_EXCEPTION和ALL_COMPLETE,默认设置为ALL_COMPLETED。

def main4():
    exe = ThreadPoolExecutor(max_workers=2)
    l = [exe.submit(task, i) for i in [2, 1, 3]]
    s1, s2 = wait(l, return_when='FIRST_COMPLETED')
    print([f.result() for f in s1])
    print([f.result() for f in s2])
    '''
    return_when 默认时
    收到了1
    收到了2
    收到了3
    [1, 2, 3]
    []
    
    return_when='FIRST_COMPLETED'
    收到了1
    [1]
    收到了2
    收到了3
    [3, 2]
    '''


三、future对象

submit函数返回future对象,map函数返回future对象对象的列表。

future.cancel() 取消任务

future.cancelled() 排断任务是否取消

future.running() 是否运行

future.done()  是否结束
add_done_callback(fn) 添加结束或取消时的回调函数

四、异常

concurrent.futures.CancelledError
    当future对象取消
concurrent.futures.TimeoutError
    当future对象运行到给定时间
concurrent.futures.BrokenExecutor
    执行器异常,不能调用submit,不能执行新的任务
concurrent.futures.thread.BrokenThreadPool
    当线程池中的worker不能初始化
concurrent.futures.process.BrokenProcessPool
    当进程被终止,比如从外部kill

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值