文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Python 中怎么使用Asyncio实现异步编程

2023-06-17 03:48

关注

Python 中怎么使用Asyncio实现异步编程,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。

异步是怎么一回事?

在传统的顺序编程中, 所有发送给解释器的指令会一条条被执行。此类代码的输出容易显现和预测。 但是…

譬如说你有一个脚本向3个不同服务器请求数据。  有时,谁知什么原因,发送给其中一个服务器的请求可能意外地执行了很长时间。想象一下从第二个服务器获取数据用了10秒钟。在你等待的时候,整个脚本实际上什么也没干。如果你可以写一个脚本可以不去等待第二个请求而是仅仅跳过它,然后开始执行第三个请求,然后回到第二个请求,执行之前离开的位置会怎么样呢。就是这样。你通过切换任务最小化了空转时间。尽管如此,当你需要一个几乎没有I/O的简单脚本时,你不想用异步代码。

还有一件重要的事情要提,所有代码在一个线程中运行。所以如果你想让程序的一部分在后台执行同时干一些其他事情,那是不可能的。

准备开始

这是 asyncio 主概念最基本的定义:

class Task(futures.Future):       def __init__(self, coro, loop=None):         super().__init__(loop=loop)         ...         self._loop.call_soon(self._step)      def _step(self):             ...         try:             ...             result = next(self._coro)         except StopIteration as exc:             self.set_result(exc.value)         except BaseException as exc:             self.set_exception(exc)             raise         else:             ...             self._loop.call_soon(self._step)

现在我们看一下所有这些如何融为一体。正如我之前提到的,异步代码在一个线程中运行。

Python 中怎么使用Asyncio实现异步编程

从上图可知:

消息循环是在线程中执行

从队列中取得任务

每个任务在协程中执行下一步动作

如果在一个协程中调用另一个协程(await  <coroutine_name>),会触发上下文切换,挂起当前协程,并保存现场环境(变量,状态),然后载入被调用协程

如果协程的执行到阻塞部分(阻塞I/O,Sleep),当前协程会挂起,并将控制权返回到线程的消息循环中,然后消息循环继续从队列中执行下一个任务...以此类推

队列中的所有任务执行完毕后,消息循环返回***个任务

异步和同步的代码对比

现在我们实际验证异步模式的切实有效,我会比较两段 python 脚本,这两个脚本除了 sleep 方法外,其余部分完全相同。在***个脚本里,我会用标准的  time.sleep 方法,在第二个脚本里使用 asyncio.sleep 的异步方法。

这里使用 Sleep 是因为它是一个用来展示异步方法如何操作 I/O 的最简单办法。

使用同步 sleep 方法的代码:

import asyncio   import time   from datetime import datetime   async def custom_sleep():       print('SLEEP', datetime.now())     time.sleep(1)  async def factorial(name, number):       f = 1     for i in range(2, number+1):         print('Task {}: Compute factorial({})'.format(name, i))         await custom_sleep()         f *= i     print('Task {}: factorial({}) is {}\n'.format(name, number, f))   start = time.time()   loop = asyncio.get_event_loop()  tasks = [       asyncio.ensure_future(factorial("A", 3)),     asyncio.ensure_future(factorial("B", 4)), ] loop.run_until_complete(asyncio.wait(tasks))   loop.close()  end = time.time()   print("Total time: {}".format(end - start))

脚本输出:

Task A: Compute factorial(2)   SLEEP 2017-04-06 13:39:56.207479   Task A: Compute factorial(3)   SLEEP 2017-04-06 13:39:57.210128   Task A: factorial(3) is 6  Task B: Compute factorial(2)   SLEEP 2017-04-06 13:39:58.210778   Task B: Compute factorial(3)   SLEEP 2017-04-06 13:39:59.212510   Task B: Compute factorial(4)   SLEEP 2017-04-06 13:40:00.217308   Task B: factorial(4) is 24  Total time: 5.016386032104492

使用异步 Sleep 的代码:

import asyncio   import time   from datetime import datetime   async def custom_sleep():       print('SLEEP {}\n'.format(datetime.now()))     await asyncio.sleep(1)  async def factorial(name, number):       f = 1     for i in range(2, number+1):         print('Task {}: Compute factorial({})'.format(name, i))         await custom_sleep()         f *= i     print('Task {}: factorial({}) is {}\n'.format(name, number, f))   start = time.time()   loop = asyncio.get_event_loop()  tasks = [       asyncio.ensure_future(factorial("A", 3)),     asyncio.ensure_future(factorial("B", 4)), ] loop.run_until_complete(asyncio.wait(tasks))   loop.close()  end = time.time()   print("Total time: {}".format(end - start))

脚本输出:

Task A: Compute factorial(2)   SLEEP 2017-04-06 13:44:40.648665  Task B: Compute factorial(2)   SLEEP 2017-04-06 13:44:40.648859  Task A: Compute factorial(3)   SLEEP 2017-04-06 13:44:41.649564  Task B: Compute factorial(3)   SLEEP 2017-04-06 13:44:41.649943  Task A: factorial(3) is 6  Task B: Compute factorial(4)   SLEEP 2017-04-06 13:44:42.651755  Task B: factorial(4) is 24  Total time: 3.008226156234741

从输出可以看到,异步模式的代码执行速度快了大概两秒。当使用异步模式的时候(每次调用 await asyncio.sleep(1)  ),进程控制权会返回到主程序的消息循环里,并开始运行队列的其他任务(任务A或者任务B)。

关于Python 中怎么使用Asyncio实现异步编程问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注编程网行业资讯频道了解更多相关知识。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯