Python--Python并行编程实战(第2版) 异步/协程
python 并行编程
异步模型 asynchronous model
在并发异步执行模型中,不同任务的执行在时间轴上有交叠,所有活动都在单一控制流作用下完成(单线程)。一旦启动,任务的执行可以暂挂,过一段时间后再恢复,与当前其他任务的执行交替进行。
concurrent.futures 模块
concurrent.futures.Executor
抽象类,提供了异步执行调用的方法
concurrent.futures.ThreadPoolExecutor
异步线程池
init(max_workers=None)
- 参数
- max_workers: 最大工作线程数,默认是处理器个数乘以5
concurrent.futures.ProcessPoolExecutor
异步线程池
init(max_workers=None)
- 参数
- max_workers: 最大工作进程数,默认是处理器个数
asyncio 模块
- 事件循环(event loop)
- 协程(coroutine)
- Future
- Task
asyncio.get_event_loop()
获取当前线程中的事件循环
- call_later()
- call_soon()
- time(): 根据事件循环的内部时钟,这会将当前时间作为一个float值返回
- run_foever()
- run_until_complete()
- stop()
- close()
示例
import asyncio
import random
import time
def task_a(end_time, loop):
print('task a called')
time.sleep(random.randint(0, 5))
if (loop.time() + 1.0) < end_time:
loop.call_later(1, task_b, end_time, loop)
else:
loop.stop()
def task_b(end_time, loop):
print('task b called')
time.sleep(random.randint(3, 7))
if (loop.time() + 1.0) < end_time:
loop.call_later(1, task_c, end_time, loop)
else:
loop.stop()
def task_c(end_time, loop):
print('task c called')
time.sleep(random.randint(5, 10))
if (loop.time() + 1.0) < end_time:
loop.call_later(1, task_a, end_time, loop)
else:
loop.stop()
def main():
loop = asyncio.get_event_loop()
end_time = loop.time() + 60
loop.call_soon(task_a, end_time, loop)
loop.run_forever()
loop.close()
if __name__ == '__main__':
main()
asyncio.set_event_loop()
设置当前线程的事件循环
asyncio.new_event_loop()
创建一个事件循环对象
asyncio.wait()
多任务执行,返回的是(done, pending)两种Future集合,done是已完成的,pedding是未完成的
asyncio.gather()
多任务执行,返回的是结果列表
协程
3.5版本之前使用注解 @asyncio.coroutine 搭配 yield from 其他协程 的模式;3.5版本之后使用async/await
asyncio.Future
result()
获取future对象的结果
cancel()
取消future对象,并调度回调
exception()
获取future对象上的异常
add_done_callback(fn)
增加一个在future完成时调用的回调函数
remove_done_callback(fn)
从future对象的回调列表中删除一个回调函数
set_result(result)
设置future的结果,并标志future已完成
set_exception(exception):
设置future异常,并标志future已完成
asyncio.Task
Future的子类
asyncio.Queue
异步队列