赞
踩
Python实现异步编程的方案有:
twisted
:使用事件驱动机制来提升python性能gevent
:使用greenlet在用户态完成栈和上下文切换来减少切换带来的性能损耗tornado
:使用生成器来保存协程上下文及状态,使用原生的python语法实现了协程asyncio
:异步编程标准化。多进程、多线程这类方案,IO的调度取决于系统;
协程,调度来自于用户。
asyncio模块实现异步,也是采用协程实现。
事件的本质就是异步。
事件源:可以产生事件的实体;
事件处理者:能处理事件的实体;
事件循环:第三方实体。
事件循环的作用是管理所有的事件,在整个程序运行过程中不断循环执行,追踪事件发生的顺序将它们放到队列中,当主线程空闲的时候,调用相应的事件处理者处理事件。
import asyncio
import time
async def do_some_work(x): # async关键字定义一个协程
print('Waiting:', x)
coroutine = do_some_work(2) # 协程的调用不会直接执行,而是返回一个协程对象
loop = asyncio.get_event_loop() # 创建一个事件循环
loop.run_until_complete(coroutine) # run_until_complete将协程注册到事件循环,并启动事件循环。
协程对象不能直接运行,在注册事件循环时,run_until_complete
将协程包装成了一个task
。task
对象是Futurn
类的子类,保存了协程运行后的状态,用于未来获取协程的结果。
import asyncio
import time
async def do_some_work(x): # async关键字定义一个协程
print('Waiting:', x)
coroutine = do_some_work(2) # 协程的调用不会直接执行,而是返回一个协程对象
loop = asyncio.get_event_loop() # 创建一个事件循环
task = loop.create_task(coroutine) # 创建task,此时的task尚未加入事件循环,状态为pending
loop.run_until_complete(task) # run_until_complete将task注册到事件循环,并启动事件循环。
# task执行完后,状态为finished
run_until_complete
参数是一个future对象
,当传入的是:
task
task
,task
是Future
的子类。asyncio.ensure_future(coroutine)
和loop.create_task(coroutine)
都可以创建task# 绑定回调函数 import asyncio import time async def do_some_work(x): # async关键字定义一个协程 print('Waiting:', x) return 'Done after {}s'.format(x) # 返回值 def callback(future): # 定义一个回调函数,最后一个参数是future对象,如果这里有多个参数,下方通过偏函数导入 print('Callback: ', future.result()) # 返回future的结果 coroutine = do_some_work(2) # 协程的调用不会直接执行,而是返回一个协程对象 loop = asyncio.get_event_loop() # 创建一个事件循环 task = loop.create_task(coroutine) # 创建task,此时的task尚未加入事件循环,状态为pending task.add_done_callback(callback) # 绑定回调函数,在task执行完毕的时候获取执行的结果 loop.run_until_complete(task) # run_until_complete将task注册到事件循环,并启动事件循环。 # task执行完后,状态为finished
coroutine执行结束时会调用回调函数,并通过参数future获取协程执行的结果,此future是没有传入的,实际上与创建的task是同一个对象
# 阻塞和await import asyncio import time now = lambda: time.time() async def do_some_work(x): print('Waiting: ', x) await asyncio.sleep(x) # 执行sleep时,await使此协程主动让出控制权,loop调用其他协程 return 'Done after {}s'.format(x) start = now() coroutine = do_some_work(2) loop = asyncio.get_event_loop() task = asyncio.ensure_future(coroutine) loop.run_until_complete(task) print('Task ret: ', task.result()) print('TIME: ', now() - start) # 以上还只有一个协程,让出控制权也暂时无用,如果有多个协程,协程A让出控制权,loop就会把控制权分配给协程B,实现了并发。 # asyncio实现并发:每当一个协程任务阻塞的时候就await,让后其他协程继续工作。 import asyncio import time now = lambda: time.time() async def do_some_work(x): print('Waiting: ', x) await asyncio.sleep(x) return 'Done after {}s'.format(x) start = now() coroutine1 = do_some_work(1) coroutine2 = do_some_work(2) coroutine3 = do_some_work(4) tasks = [ asyncio.ensure_future(coroutine1), asyncio.ensure_future(coroutine2), asyncio.ensure_future(coroutine3) ] loop = asyncio.get_event_loop() loop.run_until_complete(asyncio.wait(tasks)) # asyncio.wait(接收task列表);asyncio.gather(接收多个task) for task in tasks: print('Task ret: ', task.result()) print('TIME: ', now() - start)
From Wikipedia, an eventloop is a programming construct that waits for and dispathches enents or messages in a program.Basically an event loop lets you go, “When A happens, do B”.
In Python’s case,asyncio
was added to the standard library to provide an event loop.
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。