python asyncio_python3.8 异步 asyncio 执行顺序
先看几种协程的执行情况:
1、 协程函数中没有 await,即没有可等待对象。且 调用函数 main() 也是直接用 await 调用,即不先创建 task。
import asyncio
import time
async def first_fun(delay):
print('开始执行 first_fun 函数。')
# await asyncio.sleep(delay) # 注释掉,使其没有可等待对象。
print('first_fun 函数执行结束。')
return delay
async def second_fun(delay):
print('开始执行 second_fun 函数。')
# await asyncio.sleep(delay)
print('second_fun 函数执行结束。')
return delay
async def main():
print(f"started at {time.strftime('%X')}")
await first_fun(2) # ⑴
await second_fun(3)# ⑵
print(f"finished at {time.strftime('%X')}")
asyncio.run(main())1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
执行结果为:
started at 19:21:49
开始执行 first_fun 函数。
first_fun 函数执行结束。
开始执行 second_fun 函数。
second_fun 函数执行结束。
finished at 19:21:491
2
3
4
5
6
说明执行顺序就是 从上到下的执行顺序,即当代码运行到 (1)处时,它会先把(1)引用的函数运行结束,才会再运行(2),和普通函数调用效果一样。
2、 协程函数中没有 加入可等待对象,这里用 asyncio.sleep()进行模拟。
import asyncio
import time
async def first_fun(delay):
print('开始执行 first_fun 函数。')
await asyncio.sleep(delay)
print('first_fun 函数执行结束。')
return delay
async def second_fun(delay):
print('开始执行 second_fun 函数。')
await asyncio.sleep(delay)
print('second_fun 函数执行结束。')
return delay
async def main():
print(f"started at {time.strftime('%X')}")
await first_fun(2)
await second_fun(3)
# first = asyncio.create_task(first_fun(2))
# second = asyncio.create_task(second_fun(3))
print(f"finished at {time.strftime('%X')}")
asyncio.run(main())1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
执行结果为:
started at 19:29:04
开始执行 first_fun 函数。
first_fun 函数执行结束。
开始执行 second_fun 函数。
second_fun 函数执行结束。
finished at 19:29:091
2
3
4
5
6
可以看出,执行顺序和普通函数也没区别。执行时间,就是两个协程函数的总和。
说明:main() 函数中直接用 await 调用协程函数,就是普通的函数调用。
3、 main() 函数中创建task(), 但调用的协程函数中没有 await 可等待对象。main 中也没有用 await 来引用 task。
import asyncio
import time
async def first_fun(delay):
print('开始执行 first_fun 函数。')
# await asyncio.sleep(delay) # 注释掉,使其没有可等待对象。
print('first_fun 函数执行结束。')
return delay
async def second_fun(delay):
print('开始执行 second_fun 函数。')
# await asyncio.sleep(delay)
print('second_fun 函数执行结束。')
return delay
async def main():
print(f"started at {time.strftime('%X')}")
first = asyncio.create_task(first_fun(2)) # ⑴
print('=============')
second = asyncio.create_task(second_fun(3)) # ⑵
print(f"finished at {time.strftime('%X')}")
asyncio.run(main())1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
执行结果为:
started at 19:40:34
=============
finished at 19:40:34
开始执行 first_fun 函数。
first_fun 函数执行结束。
开始执行 second_fun 函数。
second_fun 函数执行结束。1
2
3
4
5
6
7
说明:代码运行到 ⑴ 处,它就会开辟一个“协程分支”,被调用的 first_fun(2) 会进入那个“分支”运行,然后马上运行下面的代码,不会影响 “主协程” 的运行脚步。
4、 main() 函数中创建task(), 调用的协程函数中有 await 可等待对象。 但 main 中也没有用 await 来引用 task。
import asyncio
import time
async def first_fun(delay):
print('开始执行 first_fun 函数。')
await asyncio.sleep(delay) # 加入模拟的可等待对象。
print('first_fun 函数执行结束。')
return delay
async def second_fun(delay):
print('开始执行 second_fun 函数。')
await asyncio.sleep(delay)
print('second_fun 函数执行结束。')
return delay
async def main():
print(f"started at {time.strftime('%X')}")
first = asyncio.create_task(first_fun(2))
print('=============')
second = asyncio.create_task(second_fun(3))
print(f"finished at {time.strftime('%X')}")
asyncio.run(main())1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
执行结果为:
started at 19:56:24
=============
finished at 19:56:24
开始执行 first_fun 函数。
开始执行 second_fun 函数。1
2
3
4
5
从结果中看出,协程分支中有了可等待对象,但因为main函数中没有用 await来引用 task,所以就获取不到协程分支中 等待 运行之后的结果了。 因为 还没还没等到支协程返回结果,主线程已经结束了。
5、 main() 函数中创建task(), 但调用的协程函数中有 await 可等待对象。 main 中,只用 await 来引用 了一个task,等待2秒的那个 first。
import asyncio
import time
async def first_fun(delay):
print('开始执行 first_fun 函数。')
await asyncio.sleep(delay)
print('first_fun 函数执行结束。')
return delay
async def second_fun(delay):
print('开始执行 second_fun 函数。')
await asyncio.sleep(delay)
print('second_fun 函数执行结束。')
return delay
async def main():
print(f"started at {time.strftime('%X')}")
first = asyncio.create_task(first_fun(2))
print('=============')
second = asyncio.create_task(second_fun(3))
await first # ⑴
print(f"finished at {time.strftime('%X')}")
asyncio.run(main())1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
运行结果为:
started at 20:10:00
=============
开始执行 first_fun 函数。
开始执行 second_fun 函数。
first_fun 函数执行结束。
finished at 20:10:021
2
3
4
5
6
此时 代码 ⑴ 的 await 在等待接收 first_fun 协程运行结束, 但没有等待 second_fun,所以 还没运行到 second_fun 函数执行结束,主线程已经结束了。
6、 main() 函数中创建task(), 但调用的协程函数中有 await 可等待对象。 main 中,只用 await 来引用 了一个task,等待3秒的那个second。
import asyncio
import time
async def first_fun(delay):
print('开始执行 first_fun 函数。')
await asyncio.sleep(delay)
print('first_fun 函数执行结束。')
return delay
async def second_fun(delay):
print('开始执行 second_fun 函数。')
await asyncio.sleep(delay)
print('second_fun 函数执行结束。')
return delay
async def main():
print(f"started at {time.strftime('%X')}")
first = asyncio.create_task(first_fun(2))
print('=============')
second = asyncio.create_task(second_fun(3))
# await first # ⑴
await second
print(f"finished at {time.strftime('%X')}")
asyncio.run(main())1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
运行结果为:
started at 20:18:02
=============
开始执行 first_fun 函数。
开始执行 second_fun 函数。
first_fun 函数执行结束。
second_fun 函数执行结束。
finished at 20:18:051
2
3
4
5
6
7
此时获得的是完整的运行结果。因为这次 await 是等待 second 的运行结束。当等待3秒的second结束时,等待2秒的first已经提前结束了。所以此时 如果代码 ⑴ 即使不注释掉,运行结果也是一样的。
最后总结:
main()函数中:
asyncio.create_task():就相当于开启了一个线程。
await : 相当用线程的 join,等待协程的运行结束,再继续运行之后的代码。
如果协程最后有 return 的返回值,可以这样获取返回值:async def main():
print(f"started at {time.strftime('%X')}")
first = asyncio.create_task(first_fun(2))
second = asyncio.create_task(second_fun(3))
await first
s = await second # 获取协程的返回值。
print(s)
print(f"finished at {time.strftime('%X')}")1
2
3
4
5
6
7
8
9
10
11
python asyncio_python3.8 异步 asyncio 执行顺序相关推荐
- python两个装饰器执行顺序_python中多个装饰器的执行顺序
今天讲一下python中装饰器的执行顺序,以两个装饰器为例. 装饰器代码如下: def wrapper_out1(func): print('--out11--') def inner1(*args, ...
- python类中方法的执行顺序-Python实例化class的执行顺序实例方法
Python中实例化class的执行顺序示例详解 前言 本文主要介绍了关于Python实例化class的执行顺序的相关内容,下面话不多说了,来一起看看详细的介绍吧 Python里对类的实例化时有怎样的 ...
- python两个装饰器执行顺序_python中多个装饰器的执行顺序详解
装饰器是程序开发中经常会用到的一个功能,也是python语言开发的基础知识,如果能够在程序中合理的使用装饰器,不仅可以提高开发效率,而且可以让写的代码看上去显的高大上^_^ 使用场景 可以用到装饰器的 ...
- python装饰器调用顺序_聊一聊Python装饰器的代码执行顺序
为什么写这篇文章? 起因是QQ群里边有人提了一个问题:之前导入模块只需要1~2秒,为什么现在变成需要2~3分钟? 我的第一感觉是:是不是导入的模块顶层代码里边,做了什么耗时的事情.隔了一天,他的问题解 ...
- Python装饰器-装饰流程,执行顺序
最近看到一个关于Flask的CTF(RealWorld CTF 2018 web题bookhub)文章 其中的一个trick是装饰器的顺序问题,就想写篇博客回顾下装饰器~ 首先强烈推荐很久之前看的一篇 ...
- python类中方法的执行顺序-Python中实例化class的执行顺序示例详解
前言 本文主要介绍了关于Python实例化class的执行顺序的相关内容,下面话不多说了,来一起看看详细的介绍吧 Python里对类的实例化时有怎样的顺序 一般来说一个类里面有类变量和方法,比如我们定 ...
- python多个装饰器执行顺序_Python面试题之多个装饰器执行顺序
疑问 大部分涉及多个装饰器装饰的函数调用顺序时都会说明它们是自上而下的,比如下面这个例子:def decorator_a(func): print 'Get in decorator_a' def i ...
- python多个for的执行顺序-python_装饰器篇(多个装饰器下的执行顺序)
在之前的帖子中,简单自我总结了装饰器的几个情况以及基本上使用,那么有基本上说的都是单个的装饰器修饰方法 有时候我们会发现一个方法上面有多个装饰器 如下: @dec2 @dec def a(a): if ...
- python多个for的执行顺序-python顺序执行多个py文件
假如我要执行code目录下的python程序,假设该目录下有1.py,2.py,3.py,4.py四个文件,但是我想执行1.py,2.py,4.py,则可在该目录下创建一个python文件,代码如下: ...
最新文章
- php怎么复制变量,php - 将用户名保留在变量/函数中供以后使用[复制] - SO中文参考 - www.soinside.com...
- Windows下Git库的创建
- Spark1.0.0 开发环境高速搭建
- 函数名的应用(第一对象) 闭包 装饰器
- 深度学习笔记第一门课​第四周:深层神经网络
- Dojo 之 面向对象
- 解决Windows10搜索框空白的问题
- .NET中生成动态验证码
- mysql时长用什么类型_MySQL 日期时间类型怎么选?千万不要乱用!
- 【个人笔记 - 目录】OpenCV4 C++ 快速入门 30讲
- oripa手机版_ORIPA - Origami Pattern Editor
- Excel: 如何对Excel2007工作表做统一编辑修改
- 洛谷2678跳石头----二分答案入门
- dubbo面试题-dubbo源码解析
- 万字详解 GoF 23 种设计模式(多图、思维导图、模式对比),让你一文全面理解
- Android手机游戏开发入门教程
- html制作论坛页面模板,Discuz3.3仿小米论坛风格整站模板制作教程——1、新建模板方案...
- DTM、DEM与DSM的区别及其他
- 如何破解linux密码
- 【前端】在Vue2中使用Vanta.js炫酷动态背景(全屏背景)