python中Task封装协程的知识点总结

作者:小妮浅浅 时间:2022-10-25 13:25:02 

说明

1、Task是Future的子类,Task是对协程的封装,我们把多个Task放在循环调度列表中,等待调度执行。

2、Task对象可以跟踪任务和状态。Future(Task是Futrue的子类)为我们提供了异步编程中最终结果的处理(Task类还具有状态处理功能)。

3、把协程封装成Task,加入一个队列等待调用。刚创建Task的时候不执行,遇到await就执行。

实例


import asyncio

async def func():
print(1)
await asyncio.sleep(2)
print(2)
return "返回值"

async def main():
print("main开始")

# 创建协程,将协程封装到Task对象中并添加到事件循环的任务列表中,等待事件循环去执行(默认是就绪状态)。
# 在调用
task_list = [
asyncio.create_task(func(), name="n1"),
asyncio.create_task(func(), name="n2")
]

print("main结束")

# 当执行某协程遇到IO操作时,会自动化切换执行其他任务。
# 此处的await是等待所有协程执行完毕,并将所有协程的返回值保存到done
# 如果设置了timeout值,则意味着此处最多等待的秒,完成的协程返回值写入到done中,未完成则写到pending中。
done, pending = await asyncio.wait(task_list, timeout=None)
print(done, pending)

asyncio.run(main())

知识点扩展:

Task 概念及用法

  • Task,是 python 中与事件循环进行交互的一种主要方式。

创建 Task,意思就是把协程封装成 Task 实例,并追踪协程的 运行 / 完成状态,用于未来获取协程的结果。

  • Task 核心作用:在事件循环中添加多个并发任务;

具体来说,是通过 asyncio.create_task() 创建 Task,让协程对象加入时事件循环中,等待被调度执行。

注意:Python 3.7 以后的版本支持 asyncio.create_task(),在此之前的写法为 loop.create_task(),开发过程中需要注意代码写法对不同版本 python 的兼容性。

  • 需要指出的是,协程封装为 Task 后不会立马启动,当某个代码 await 这个 Task 的时候才会被执行。

当多个 Task 被加入一个 task_list 的时候,添加 Task 的过程中 Task 不会执行,必须要用 await asyncio.wait() 或 await asyncio.gather() 将 Task 对象加入事件循环中异步执行。

  • 一般在开发中,常用的写法是这样的:

-- 先创建 task_list 空列表;
-- 然后用 asyncio.create_task() 创建 Task;
-- 再把 Task 对象加入 task_list;
-- 最后使用 await asyncio.wait 或 await asyncio.gather 将 Task 对象加入事件循环中异步执行。

注意:创建 Task 对象时,除了可以使用 asyncio.create_task() 之外,还可以用最低层级的 loop.create_task() 或 asyncio.ensure_future(),他们都可以用来创建 Task 对象,其中关于 ensure_future 相关内容本文接下来会一起讲。

Task 用法代码示例:


import asyncio
import arrow

def current_time():
   '''
   获取当前时间
   :return:
   '''
   cur_time = arrow.now().to('Asia/Shanghai').format('YYYY-MM-DD HH:mm:ss')
   return cur_time

async def func(sleep_time):
   func_name_suffix = sleep_time        # 使用 sleep_time(函数 I/O 等待时长)作为函数名后缀,以区分任务对象
   print(f"[{current_time()}] 执行异步函数 {func.__name__}-{func_name_suffix}")
   await asyncio.sleep(sleep_time)
   print(f"[{current_time()}] 函数 {func.__name__}-{func_name_suffix} 执行完毕")
   return f"【[{current_time()}] 得到函数 {func.__name__}-{func_name_suffix} 执行结果】"

async def run():
   task_list = []
   for i in range(5):
       task = asyncio.create_task(async_func(i))
       task_list.append(task)

done, pending = await asyncio.wait(task_list, timeout=None)
   for done_task in done:
       print((f"[{current_time()}] 得到执行结果 {done_task.result()}"))

def main():
   loop = asyncio.get_event_loop()
   loop.run_until_complete(run())

if __name__ == '__main__':
   main()

来源:https://www.py.cn/jishu/jichu/31729.html

标签:python,Task,封装协程
0
投稿

猜你喜欢

  • 将Python中的数据存储到系统本地的简单方法

    2021-08-22 18:15:55
  • 深入理解JavaScript作用域和作用域链

    2024-04-10 13:54:17
  • 详解pandas获取Dataframe元素值的几种方法

    2022-12-28 07:30:01
  • asp如何创建Word 文件?

    2009-11-14 20:47:00
  • Python实现冒泡排序算法的示例解析

    2021-03-17 10:34:10
  • Python练习之读取XML节点和属性值的方法

    2021-03-25 19:01:06
  • sqlserver 脚本和批处理指令小结

    2012-05-22 18:56:55
  • Python兔子毒药问题实例分析

    2023-11-14 11:23:56
  • python中列表和元组的区别

    2022-05-21 16:06:00
  • keras使用Sequence类调用大规模数据集进行训练的实现

    2021-01-03 20:24:35
  • Python全局变量关键字global的简单使用

    2022-01-29 11:03:49
  • 机器学习python实战之决策树

    2021-07-21 12:46:13
  • Python使用Matplotlib实现Logos设计代码

    2021-02-04 19:18:34
  • Centos7 安装 PHP7最新版的详细教程

    2023-10-16 21:14:12
  • 在python带权重的列表中随机取值的方法

    2022-05-09 01:44:25
  • python安装dlib库报错问题及解决方法

    2023-01-27 16:24:41
  • java使用mysql预编译语句查询优势及示例详解

    2024-01-13 21:15:00
  • python实现百万答题自动百度搜索答案

    2021-10-06 03:57:11
  • JavaScript深入理解作用域链与闭包详情

    2024-04-19 10:04:07
  • 详解Python如何实现发送带附件的电子邮件

    2022-03-20 13:33:46
  • asp之家 网络编程 m.aspxhome.com