python asyncio笔记

1.什么是coroutinehtml

coroutine,最先我是在lua里面看到的,coroutine最大的好处是能够保存堆栈,让程序得以继续执行,在python里面,通常是利用yield来实现,具体能够看以下文章:python

http://www.cnblogs.com/tqsummer/archive/2010/12/27/1917927.htmlwindows

 

python中的yield以及yield from语法可让程序支持coroutine服务器

 

2.asyncio异步

Python3中,提供了基于coroutine的异步IO库,就是asynciosocket

https://docs.python.org/3/library/asyncio.htmlasync

 

2.1 event looptcp

asyncio库一个重要的概念就是事件循环,只有启动事件循环之后,才可让coroutine任务得以继续执行,若是event loop中止或者暂停,那么整个异步io也中止或者暂停,相似于操做系统的事件循环机制函数

asyncio的内部是基于selector(也多是epoll)或者windows iocp来实现的,这也是为何须要启动一个event loopevent loop能够当作是对各个平台的异步IO"等待"这个操做的封装工具

 

2.2 asyncio

cotoutine

coroutine即为一个支持写成的函数,能够利用iscoroutinefunction来判断是否coroutine函数,这个函数须要@asyncio.coroutine来修饰

利用@asyncio.coroutine修饰之后,这个函数能够支持await(python 3.5) 或者 yield from语法,一旦执行yield from 语法之后,asyncio将会挂起当前的coroutine,去执行其余的coroutine

 

以下代码:

 

当开始运行event loop之后

1.开始执行sleep3s

2.当程序开始进入睡眠之后,event loop不会中止当前线程,而是挂起当前函数,执行下一个coroutine,sleep5s

3.sleep5s开始进入睡眠,挂起当前的函数

4.event loop检测到sleep 3s时间已经到了,因而从新执行被挂起的sleep3s,sleep3s执行完毕

5.sleep5s时间已经到了,因而从新执行被挂起的sleep5s,sleep5s执行完毕

 

基于coroutine的服务器

 

 

如上图,_tcp_listen建立了一个tcp 服务器,而且收到一个tcp连接之后,建立一个_tcp_recv的任务,而后开始监听tcp链接的数据

 

与基于回调的库区别

coroutine版本代码在recv上逻辑处理代码是线性的而不是断裂的,基于回调的代码则常常须要乱跳,可读性较高

并且不用建立临时的数据去保存一些变量,上图中的self.tcp_clients就是由于老版本是基于回调的,须要这个数据成员去存储(懒得再本身从新写代码,这分是重构某个工具到通常时候的代码)

 

扩展asyncio

 

由于项目里面须要知道对方udp的地址,所以须要扩展sock_recv,利用socket自己提供的recv_from

看了下loop.socket_recv的源码,loop.socket_recv

 

 

 

在调用以前 必须将socket设置为非阻塞,不然会报错

关键点在于add_reader这个函数将socket传送给异步IO(默认是selector),而且传送一个回调进去(在这个例子里面是_sock_recv本身这个函数,只要有数据能够读取之后,将会再次调用_sock_recv这个函数

 

asyncio也不止支持sleep以及io操做,还支持多进程,lock等操做

 

只要将上图的data = sock.recv(n)改成data, addr = sock.recv_from(n)就能够了

 

3.5中,新增长了async以及await的语法,用于代替asynio.coroutine以及yield from

Python3.5 async以及await

https://www.python.org/dev/peps/pep-0492/

相关文章
相关标签/搜索