Python异步编程

参考文章:
1.廖雪峰教程-异步
3.Improve Your Python: 'yield' and Generators Explained
4.[译] Python 3.5 协程究竟是个啥

  • 概念:同步、异步、阻塞、非阻塞
    请参见我的之前的学习笔记

  • 为什么要使用异步?
    CPU和IO的速度差异大,为了同时执行其他的任务,我们可以采用多线程和多进程,也可以采用异步,正如上面的学习笔记,异步是一种分离调用和结果两个过程的机制,因此可以用异步来解决IO问题。

  • Coroutines and Subroutines 协程和子程序
    见上面的参考文章3

子程序就是协程的一种特例

协程和子程序一样都可以跟主程序进行交互,但是协程可以保存上下文。

  • 消息模型是如何解决同步IO必须等待IO操作这一问题的呢?

当遇到IO操作时,代码只负责发出IO请求,不等待IO结果,然后直接结束本轮消息处理,进入下一轮消息处理过程。当IO操作完成后,将收到一条“IO完成”的消息,处理该消息时就可以直接获取IO操作结果。

  • 优点

在“发出IO请求”到收到“IO完成”的这段时间里,同步IO模型下,主线程只能挂起,但异步IO模型下,主线程并没有休息,而是在消息循环中继续处理其他消息。这样,在异步IO模型下,一个线程就可以同时处理多个IO请求,并且没有切换线程的操作。对于大多数IO密集型的应用程序,使用异步IO将大大提升系统的多任务处理能力。

  • 协程

协程看上去也是子程序,但执行过程中,在子程序内部可中断,然后转而执行别的子程序,在适当的时候再返回来接着执行。

  • 那和多线程比,协程有何优势?

最大的优势就是协程极高的执行效率。因为子程序切换不是线程切换,而是由程序自身控制,因此,没有线程切换的开销,和多线程比,线程数量越多,协程的性能优势就越明显。

  • 实例
import asyncio

@asyncio.coroutine
def getdata():
    print('getting data!')
    r = yield from asyncio.sleep(1)
    print('has got data!')

def main():
    loop = asyncio.get_event_loop()
    loop.run_until_complete(getdata())
    loop.close()

if __name__ == '__main__':
    main()

首先我们需要一个处理循环loop,这个就是前面说异步的时候说的调用者,相对IO来说执行的非常快,可以执行多个协程。协程是循环的小弟,帮loop去执行不同的调用,比如这里的getdata,r = yield from asyncio.sleep(1)这句就相对于IO操作,调用后马上返回loop,loop继续处理,知道IO处理好之后,loop就回到协程的这里继续执行。注意调用和数据返回是分开的

  • 例子2
import asyncio
import threading

@asyncio.coroutine
def getdata():
    print('getting data in thread {}...'.format(threading.current_thread()))
    r = yield from asyncio.sleep(1)
    print('has got data!')

def main():
    loop = asyncio.get_event_loop()
    coroutines = [getdata(),getdata()]
    loop.run_until_complete(asyncio.wait(coroutines))
    loop.close()

if __name__ == '__main__':
    main()

打印出的信息

getting data in thread <_MainThread(MainThread, started 3704)>...
getting data in thread <_MainThread(MainThread, started 3704)>...
has got data!
has got data!

这个例子说明,多个协程是在同一个线程中运行的,协程用于异步IO的验证

asyncio可以实现单线程并发IO操作。如果仅用在客户端,发挥的威力不大。如果把asyncio用在服务器端,例如Web服务器,由于HTTP连接就是IO操作,因此可以用单线程+coroutine实现多用户的高并发支持。
asyncio实现了TCP、UDP、SSL等协议,aiohttp则是基于asyncio实现的HTTP框架。

拓展阅读:
1.Python 异步网络爬虫 I
2.Python 异步网络爬虫 II

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

友情链接更多精彩内容