快速掌握AsyncIO---新手入门
Python AsyncIO
asyncio是从Python 3.4+开始引入的标准库,从而支持async IO,协程(coroutine)。
举个例子:假设有1个洗衣房,里面有10台洗衣机,有一个洗衣工在负责这10台洗衣机。那么洗衣房就相当于1个进程,洗衣工就相当1个线程。如果有10个洗衣工,就相当于10个线程,1个进程是可以开多线程的。这就是多线程!
那么协程呢?先不急。大家都知道,洗衣机洗衣服是需要等待时间的,如果10个洗衣工,1人负责1台洗衣机,这样效率肯定会提高,但是不觉得浪费资源吗?明明1 个人能做的事,却要10个人来做。只是把衣服放进去,打开开关,就没事做了,等衣服洗好再拿出来就可以了。就算很多人来洗衣服,1个人也足以应付了,开好第一台洗衣机,在等待的时候去开第二台洗衣机,再开第三台,……直到有衣服洗好了,就回来把衣服取出来,接着再取另一台的(哪台洗好先就取哪台,所以协程是无序的)。这就是计算机的协程!洗衣机就是执行的方法。
当你程序中方法需要等待时间的话,就可以用协程,效率高,消耗资源少。
好了!现在来总结一下:
洗衣房 ==> 进程
洗衣工 ==> 线程
洗衣机 ==> 方法(函数)
1. async await
函数前+async keyword时,实际上是创建了这个函数的wrapper,当调用这个函数时,实际上会返回一个coroutine object
首先 正常使用async awit
import asyncioasync def main():print("Hello World")print(main())
<coroutine object main at 0x7feada389ec0>
RuntimeWarning: coroutine 'main' was never awaitedprint(main())
RuntimeWarning: Enable tracemalloc to get the object allocation traceback
coroutine object与正常function不同,如果要等待coroutine object的执行结果,需要使用keyword await
来等待coroutine完成返回的结果。我们来试试await
:
import asyncioasync def main():print("Hello World")await main()
File "/Users/xxx/PycharmProjects/pythonProject/test_ansy.py", line 15await main()^
SyntaxError: 'await' outside function
await 只能在async函数中使用。但是await要在async函数中使用,而要跑async函数,需要await等待返回结果。需要使用event-loop
2. Event-loop
Event-Loop是一个在程序中等待并分发事件或者消息的设计模式
Python coroutine需要跑在event-loop中
asyncio这个包中提供了一个asyncio.run的函数,可以作为coroutine的入口,asyncio.run
会创建一个event-loop,然后将传递给他的coroutine object执行在这个event-loop上,通常asyncio.run
这个函数在程序中只会被调用一次,作为coroutine的入口
import asyncio
async def main():print("Hello World")asyncio.run(main())
Hello World
import asyncio
async def main():print("Hello World")await foo("I am foo")print("foo done")async def foo(text):print(text)# 当前coroutine放弃运行,等待5秒后返回await asyncio.sleep(5)print("wake up")asyncio.run(main())
Hello World
I am foo
wake up
foo done
asyncio.new_event_loop()
来创建一个新的Event-Loop然后通过loop.run_until_complete()
来启动一个coroutine
import asyncioasync def main():print("Hello World")await foo("I am foo")print("foo done")async def foo(text):print(text)await asyncio.sleep(2)print("wake up foo")loop = asyncio.new_event_loop()
loop.run_until_complete(main())
Hello World
I am foo
wake up foo
foo done
3. task
当foo函数sleep的时候,我们不希望等待他结束,我们希望在此期间做一些别的事情,可以使用asyncio.create_task
.asyncio.create_task 会获取当前正在运行的event-loop,然后再这个loop上schedule一个task。这个task会尽可能快的开始运行。Task是一个Future-like的object(Future后面会提到),这个object上运行着一个coroutine,Task存在的意义在于让用户在Event-Loop上运行coroutine。那么为什么说是尽可能快的呢?先看接下来这个例子
import asyncioasync def main():print("Hello World")task = asyncio.create_task(foo("I am foo"))print("foo done")await taskasync def foo(text):print(text)await asyncio.sleep(1)print("wake up")asyncio.run(main())
Hello World
foo done
I am foo
wake up
Surprise! “foo done"在"I am foo"之前被print了出来,这是因为create_task只是在Running Event-Loop上schedule了一个task,并没有立刻开始运行,因为main还没有暂停执行进入等待,也没执行结束,所以main会继续执行。当main执行到await task
时,main暂停执行进入等待,下一个在Event-Loop上的task才开始执行,也就是foo。所以我们先看到了"foo done”,然后才是"I am foo"。接下来foo进入了sleep,暂停执行进入等待,而main()在等待foo的执行结果,Event-Loop上已经没有其他可以继续执行的task了,所以程序等待foo的asyncio.sleep(1)
结束,最后print “wake up”。
以上这种scheduling的方式叫做cooperative scheduling,一个Event-Loop在同一时间只运行一个Task。当一个Task awaits另一个Task(Future)完成时,当前Task会暂时停止执行,等待Future的结果,然后Event-Loop会让别的Task,Future callback(后面有提到),或者IO开始执行。
这里就要提到asyncio.Future的定义了。
Future
asyncio.create_task
的返回是task,task的定义是:
asyncio.tasksclass Task(Future[_T], Generic[_T])
future是
asyncio.futuresclass Future(Awaitable[_T], Iterable[_T])
Task它继承了Future,Future代表一个async operation在未来的最终结果。要等待这个task完成返回最终结果,我们可以使用前面提到的await
keyword,这是因为Future是Awaitable
的。
import asyncioasync def main():print("Hello World")task = asyncio.create_task(foo("I am foo"))await taskprint("foo done")async def foo(text):print(text)await asyncio.sleep(1)print("wake up")asyncio.run(main())
Hello World
I am foo
wake up
foo done
这里可以看到,main()中的await task
让main等待foo执行结束后,才继续print “foo done”。
你可能还想问,我们如何获取到task的返回结果呢?:
import asyncioasync def main():task_foo = asyncio.create_task(foo("I am foo"))task_bar = asyncio.create_task(bar())foo_res = await task_fooawait task_barprint(foo_res)async def foo(text):print(text)await asyncio.sleep(4)print("wake up")return "returns " + textasync def bar():for i in range(10):print(i)await asyncio.sleep(1)asyncio.run(main())
I am foo
0
1
2
3
wake up
4
5
6
7
8
9
returns I am foo
res = await task
可以让task的返回值被赋予到res上。
Future同时也可以用来设置callback,当Future执行完成后,callback会被执行
import asyncioasync def main():task_foo = asyncio.create_task(foo("I am foo"))task_foo.add_done_callback(callback)foo_res = await task_fooprint(foo_res)async def foo(text):print(text)await asyncio.sleep(1)print("wake up")return "returns " + textdef callback(future):print("Future has result:", future.result())print("I am callback")asyncio.run(main())
I am foo
wake up
Future has result: returns I am foo
I am callback
returns I am foo
快速掌握AsyncIO---新手入门相关推荐
- 新手入门 如何快速找到Python进阶路线?
新手入门 如何快速找到Python进阶路线?Python作为一种开放源代码的脚本编程语言,常用于开发各种程序.随着近几年人工智能的火爆,Python一度受到众多程序员的追捧,成为首选的入门编程语言.很 ...
- 计算机入门新人必学,电脑新手入门教程 让你快速上手
随着互联网时代的快速发展,电脑发展也相当的成熟,新手学电脑可以快速入门,是每个新手梦寐以求的事情,但是不会所有人都可以快速上手,最近很多用户咨询我关于零基础学电脑先学什么,或者是电脑新手入门必学什么东 ...
- 快速理解j=j++ 和 j=++j(新手入门)
快速理解j = j++ 和 j = ++ j(新手入门): j = j++ ,代码如下: public class TestDemo {/*** @param args*/public static ...
- 人工智能新手入门学习路线!附学习资源合集
有段时间没跟大家分享编程资源福利了!今天为大家整理了人工智能新手入门学习路线,同时附700分钟的学习资源合集,相信这套福利可以帮你顺利入行AI!文末领取全部资料. 一.AI基础好课学习资料整理(约31 ...
- 【原创】新手入门一篇就够:从零开发移动端IM
一.前言 IM发展至今,已是非常重要的互联网应用形态之一,尤其移动互联网时代,它正以无与论比的优势降低了沟通成本和沟通代价,对各种应用形态产生了深远影响. 做为IM开发者或即将成为IM开发者的技术人员 ...
- 课程上线 -“新手入门 : Windows Phone 8.1 开发”
经过近1个月的准备和录制,"新手入门 : Windows Phone 8.1 开发"系列课程已经在Microsoft 虚拟学院上线,链接地址为:http://www.microso ...
- 新手入门机器学习十大算法
新手入门机器学习十大算法 2018年9月17日 磐石 TensorFlowNews, 机器学习 0 在机器学习的世界中,有一种被称为"无免费午餐"的定理. 它意在说明没有哪种算法能 ...
- Windows学习总结(6)——MindManager新手入门教程
2019独角兽企业重金招聘Python工程师标准>>> MindManager新手入门教程 MindManager是一款创造.管理和交流思想的思维导图软件,其直观清晰的可视化界面和强 ...
- Docker新手入门:基本用法
Docker新手入门:基本用法 1.Docker简介 1.1 第一本Docker书 工作中不断碰到Docker,今天终于算是正式开始学习了.在挑选系统学习Docker以及虚拟化技术的书籍时还碰到了不少 ...
- 如何学习Linux / 新手入门
如何学习Linux / 新手入门 一.从基础开始:常常有些朋友在Linux论坛问一些问题,不过,其中大多数的问题都是很基础的.例如:为什么我使用一个命令的时候,系统告诉我找不到该目录,我要如何限制使用 ...
最新文章
- lookout筛选相同信息_信息流广告4大行业案例总结分析(不会操作那就抄吧,建议收藏)...
- h5文字垂直居中_CSS实现居中的几种方式你都了解吗?
- 爬虫智能解析库 Readability 和 Newspaper 的用法
- 互联网公司的黑话,你都经历过吗?
- html----选项卡自动切换以及鼠标悬停时停止(js)
- 绚丽的javascript拾色器(不兼容IE8及以下)
- WinRar注册机或注册码
- easypoi 语法_【语法微课合集】50堂英语语法微课,视频课件免费下载,建议收藏或转发朋友圈...
- CSS动画文字闪烁问题
- 车联网TCU USB的配置和使用
- VLC模拟TS直播流
- 全国大学生数学建模竞赛(建模全过程)
- 【Netty官方文档翻译】引用计数对象(reference counted objects)
- element表格左对齐方法
- 什么是c语言系统调用,什么是系统调用?为什么要用系统调用?
- 巴贝奇计算机科学思想,计算机之父巴贝奇_图灵_计算机科学之父
- php对接第三方接口
- Spring Cloud Config教程(四)快速开始
- 支付宝生活缴费视频课程
- 完全禁止WIN10自动更新的方法