先贴份官方文档吧asyncio — 异步 I/O 协程与任务
学协程是先从缪雪峰老师的异步IO看起的,但确实看的云里雾里,教程很简短但内容过于丰富让人摸不着头脑。之后就是在评论里顺藤摸瓜了一个博主的IO协程博客,很全面也很生动,贴一下链接
Python异步IO之协程(一):从yield from到async的使用
Python异步IO之协程(二):使用asyncio的不同方法实现协程
这里提醒一下对async with一无所知的朋友,在百度搜索里搜不到什么async with的相关教程,如果碰巧你还对with、上下文管理器也不懂,就会连教程也看不懂。先把with搞懂了再看那篇少的可怜的教程会好很多!
个人比较推荐看一下这个台湾博主的教程,思路很适合新手,会从头讲起,包括asyncio的get_event_loop()等函数怎么用,coroutine object和task转换之类。他比较注重怎么使用协程的整体过程,其他博客注重协程的语法,顺序没这么连贯,可能将函数就是单独讲,逻辑上连不起来。
python的asyncio模組(一):異步執行的好處
python的asyncio模組(二):異步程式設計基本概念
python的asyncio模組(三):建立Event Loop和定義協程
python的asyncio模組(四):Event loop常用API
从这篇开始就有点不知所云了,后面接着的就不贴了
python的asyncio模組(五):Future對象與Task對象
突然又看到一篇很好的协程文章:Python黑魔法 — 异步IO( asyncio) 协程
深入理解asyncio(二)
一、概念
在segmentfault看到一个很好的解释:所有协程都是运行在一个线程里,不像多线程那样,由操作系统强制线程暂停执行(挂起)。在协程里,是需要协程主动交出执行权限(可以是协程执行完,或是await,yield等等)
asyncio.create_task()
asyncio.ensure_future()
这个链接的最后一个例子比较好地阐述了这个函数的意思:await这个关键词以及asyncio.wait asyncio.gather
之前看其他博客感觉这个函数只起到了一个将协程包装成task对象的作用。但其实它还起到将括号内的协程加入到“task”中,保证了当我们启动eventloop的时候(使用run_until_complete或fun_forever函数时),就会按照task产生的先后顺序依次去执行,就算run_until_complete的参数task并未包含这个协程。
import asyncio
async def a():
print ("a")
async def b():
print ("b")
asyncio.ensure_future(a())
bb=asyncio.ensure_future(b())
loop = asyncio.get_event_loop()
loop.run_until_complete(bb)
#虽然传入的参数是task-bb,但是task-a却会执行,
#并且是第一个执行,首先打印a,其次打印b
上文链接对await关键词,即遇到await协程是否立即挂起去执行其他协程也有一个非常好的阐述:
异步io的关键在于,await io操作,此时,当前携程就会被挂起,时间循环转而执行其他携程,但是要注意前面这句话,并不是说所有携程里的await都会导致当前携程的挂起,要看await后面跟的是什么,如果跟的是我们定义的携程,则会执行这个携程,如果是asyncio模块制作者定义的固有携程,比如模拟io操作的asyncio.sleep,以及io操作,比如网络io:asyncio.open_connection这些,才会挂起当前携程。
loop.run_until_complete()
loop.run_forever()
这两个函数暂时理解为开启loop循环的唯一方式。只写loop.create_task()
并不能开启loop循环。
再注意一点,当写了loop.run_forever()
,随后再跟loop.create_task()
函数,这个创建的task会立刻开始执行,并不用再加其他函数了。