课程咨询: 400-996-5531 / 投诉建议: 400-111-8989
认真做教育 专心促就业
随着互联网的不断发展,python编程开发成为了当下的热门学习技术之一,而今天我们就通过案例分析来了解一下,python编程常见的一些协程方式都有哪些类型。
1、async/await
async/await是使用python协程的关键,从结构上来看,asyncio实质上是一个异步框架,async/await是为异步框架提供的API已方便使用者调用,所以使用者要想使用async/await编写协程代码,目前必须机遇asyncio或其他异步库。
2、Future
在实际开发编写异步代码时,为了避免太多的回调方法导致的回调地狱,但又需要获取异步调用的返回结果结果,聪明的语言设计者设计了一个叫Future的对象,封装了与loop的交互行为。其大致执行过程为:程序启动后,通过add_done_callback方法向epoll注册回调函数,当result属性得到返回值后,主动运行之前注册的回调函数,向上传递给coroutine。这个Future对象为asyncio.Future。
但是,要想取得返回值,程序必须恢复恢复工作状态,而由于Future对象本身的生存周期比较短,每一次注册回调、产生事件、触发回调过程后工作可能已经完成,所以用Future向生成器sendresult并不合适。所以这里又引入一个新的对象Task,保存在Future对象中,对生成器协程进行状态管理。
Python里另一个Future对象是concurrent.futures.Future,与asyncio.Future互不兼容,容易产生混淆。区别点在于,concurrent.futures是线程级的Future对象,当使用concurrent.futures.Executor进行多线程编程时,该对象用于在不同的thread之间传递结果。
3、Task
上文中提到,Task是维护生成器协程状态处理执行逻辑的的任务对象,Task中有一个_step方法,负责生成器协程与EventLoop交互过程的状态迁移,整个过程可以理解为:Task向协程send一个值,恢复其工作状态。当协程运行到断点后,得到新的Future对象,再处理future与loop的回调注册过程。
4、Loop
在日常开发中,会有一个误区,认为每个线程都可以有一个独立的loop。实际运行时,主线程才能通过asyncio.get_event_loop()创建一个新的loop,而在其他线程时,使用get_event_loop()却会抛错。正确的做法为通过asyncio.set_event_loop(),将当前线程与主线程的loop显式绑定。
Loop有一个很大的缺陷,就是loop的运行状态不受Python代码控制,所以在业务处理中,无法稳定的将协程拓展到多线程中运行。
【免责声明】:本内容转载于网络,转载目的在于传递信息。文章内容为作者个人意见,本平台对文中陈述、观点保持中立,不对所包含内容的准确性、可靠性与完整性提供形式地保证。请读者仅作参考。