python异步IO的发展历程
2017-12-02 20:42
337 查看
python中异步IO发展分为三个发展阶段
1.使用yield和send
2.使用@asyncio.coroutine和yield from
3.使用async/await关键字
以上代码承接上文,由此可见,yield from相当于重构之前的yield的代码,重新来一次刷新。
理解了yield from之后,async/await关键字就很好理解了,其实就是对yield from的简化。
1.使用yield和send
2.使用@asyncio.coroutine和yield from
3.使用async/await关键字
一、yield和send
def fib(n): res = [0]*n index = 0 a = 0 b = 1 while index < n: res[index] = b a, b = b, a + b index += 1 return res for res in fib(20): print(res)这是一段输出斐波那契数列的代码,需要经过数次迭代。这种方式的缺点是执行这种迭代运算需要占用大量内存,而我们最终的目的如果只是想得到某一个顺序位上的数字,该方法就不太合适了。
def fib(n): res = [0]*n index = 0 a = 0 b = 1 while index < n: yield b a, b = b, a + b index += 1 for res in fib(20): print(res)当我们使用yield 时,无须在函数内加入return,直接用for in,便可直接得到yield的值,即没运行一次,就会再执行一次next(fib(20)) (相当于执行下一次吧)。
import random import time def fib(n): index = 0 a = 0 b = 1 while index < n: sleep_cnt = yield b print('delay {0} seconds'.format(sleep_cnt)) time.sleep(sleep_cnt) a, b = b, a + b index += 1 N = 20 sfib = fib(N) res = next(sfib) while True: print(res) try: res = sfib.send(random.uniform(0, 0.5)) except StopIteration: break当我们想往线程中发送数据时,可以用到send函数,此处使用time库,虚拟一下io的延迟。
二、@asyncio.coroutine和yield from
def fibAgain(n): print('I am copy from fib') yield from fib(n) print('Copy end') for res in fibAgain(20): print(res)
以上代码承接上文,由此可见,yield from相当于重构之前的yield的代码,重新来一次刷新。
import asyncio @asyncio.coroutine def wget(host): print('wget %s...' % host) connect = asyncio.open_connection(host, 80) reader, writer = yield from connect header = 'GET / HTTP/1.0\r\nHost: %s\r\n\r\n' % host writer.write(header.encode('utf-8')) yield from writer.drain() while True: line = yield from reader.readline() if line == b'\r\n': break print('%s header > %s' % (host, line.decode('utf-8').rstrip())) # Ignore the body, close the socket writer.close() loop = asyncio.get_event_loop() tasks = [wget(host) for host in ['www.sina.com.cn', 'www.sohu.com', 'www.163.com']] loop.run_until_complete(asyncio.wait(tasks)) loop.close()以上是一个连接网站的一个例子,我们使用yield挂起需要异步IO的代码,在函数前加入@asyncio.coroutine关键字,再使用实现线程的并发。
三、async/await关键字
async def smart_fib(n): index = 0 a = 0 b = 1 while index < n: sleep_secs = random.uniform(0, 0.2) await asyncio.sleep(sleep_secs) print('Smart one think {} secs to get {}'.format(sleep_secs, b)) a, b = b, a + b index += 1 async def stupid_fib(n): index = 0 a = 0 b = 1 while index < n: sleep_secs = random.uniform(0, 0.4) await asyncio.sleep(sleep_secs) print('Stupid one think {} secs to get {}'.format(sleep_secs, b)) a, b = b, a + b index += 1 if __name__ == '__main__': loop = asyncio.get_event_loop() tasks = [ smart_fib(10)), stupid_fib(10)) ] loop.run_until_complete(asyncio.wait(tasks)) print('All fib finished.') loop.close()
理解了yield from之后,async/await关键字就很好理解了,其实就是对yield from的简化。
相关文章推荐
- Python异步非阻塞IO多路复用Select/Poll/Epoll使用
- 谈谈JavaScript异步函数发展历程
- python 异步IO
- 谈谈JavaScript异步函数发展历程
- python# 进程/线程/协程 # IO:同步/异步/阻塞/非阻塞 # greenlet gevent # 事件驱动与异步IO # Select\Poll\Epoll异步IO 以及selector
- Python开发【第九篇】:协程、异步IO
- Python笔记-IO同步和异步、 读写文件、StringIO和BytesIO
- Python中的异步io
- 异步非阻塞IO的Python Web框架--Tornado
- python 异步IO
- Python 异步 IO 的未来(从 Web 后端开发的角度)
- Python 并发编程之协程/异步IO
- Python网络编程之带select的异步IO
- Python异步非阻塞IO多路复用Select/Poll/Epoll使用,线程,进程,协程
- Socket---基于IO复用实现异步非阻塞通信 Python群聊工具
- 《每日一课》Python入门之异步IO
- 【asyncio】python异步IO
- Python学习:异步IO:协程和asyncio
- 异步IO:Python中的协程
- Python基础-异步任务IO-asyncio