RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 902586
Accepted
garrythehotdog
garrythehotdog
Asked:2020-11-06 00:03:43 +0000 UTC2020-11-06 00:03:43 +0000 UTC 2020-11-06 00:03:43 +0000 UTC

ASYNCIO. Tasks 和 Future 的区别

  • 772

问题

几天来,我无法理解 Future 和 Task 对象之间的区别。更准确地说,我不确定我是否完全理解使用的内容和位置。

我的理解

从文档中可以看出,在 asyncio 中有三种类型的 curutin 对象,任务(Task)和期货(Future)(我们称之为)。任务是计划在事件循环中运行的curout。

当协程被包装到具有 asyncio.create_task() 之类的函数的任务中时,协程会自动安排为很快运行

期货是某种存储异步操作可能结果的对象。

Future 表示异步操作的最终结果

那些。为了启动 curutina 以异步模式执行,您需要使用asyncio.create_task,但是为什么我们需要ensure_future呢?它出现在所有 asyncio 代码示例中。我在 stackoverflow 上找到了一个相关问题,但在我看来,那里没有正常的答案。下面是我使用不同选项启动 curutin 的代码 - 结果总是相同的:

import asyncio
import time

async def fetch(n):
    await asyncio.sleep(n)
    print(time.time())
    return n

loop = asyncio.get_event_loop()
# coros = [asyncio.ensure_future(fetch(i)) for i in range(2)]
# coros = [fetch(i) for i in range(3)]
coros = [loop.create_task(fetch(i)) for i in range(2)]
results = loop.run_until_complete(asyncio.gather(*coros))
print(results)

使用选项 2 和 3,这是可以理解的,因为根据文档,gather 将 curutins 转换为任务,但他们为什么使用ensure_future. 该文档还说最好使用create_task.

另请参阅 create_task() 函数,它是创建新任务的首选方式。

总而言之,我想听听关于未来是什么、它与任务有何不同以及在何处使用它的简单解释。

ps 在写这个问题的时候,我找到了这篇文章,但还不清楚)还有一个相关的问题

python
  • 1 1 个回答
  • 10 Views

1 个回答

  • Voted
  1. Best Answer
    Sergey Gornostaev
    2020-11-06T12:29:51Z2020-11-06T12:29:51Z

    目前尚不完全清楚究竟是什么不清楚,所以我会尽量简化答案,同时诉诸粗略的假设。愿我的同事们原谅我。

    协程是调用一个异步函数的结果,也就是这个函数的执行可以被挂起。由于在一般情况下无法确定执行将暂停多少次和多长时间,因此也无法确定何时完成。您的代码可以等待协程完成语句await,或者将等待留给事件循环并继续执行。

    在第一种情况下

    async def callee():
        print('Hello')
    
    async def caller():
        await callee()
        print('World')
    

    执行caller将暂停,直到callee. 此时,其他一些协程中的一些其他操作可能会继续,但caller会等待它执行的地方await。

    在第二种情况下

    async def callee():
        print('Hello')
    
    async def caller():
        asyncio.create_task(callee())
        print('World')
    

    caller立即继续工作。字符串“World”将在“Hello”之前打印。在这里我们看到我们caller设置了事件循环来执行协程callee。

    但是如果callee它返回调用者需要的一些值,但不是现在,而是当它准备好时呢?这就是期货发挥作用的地方。

    Futura(未来)——协程执行的未来结果。该方法ensure_future指示事件循环执行协程,并在调用时立即返回值将在其中的未来,但不知道何时。调用者可以像等待协程本身一样等待未来的执行

    async def callee():
        return 'Hello'
    
    async def caller():
        loop = asyncio.get_event_loop()
        future = loop.ensure_future(callee())
        result = await future
        print(result + ' World')
    

    或者他可以开展他的业务,定期检查准备情况

    async def caller():
        loop = asyncio.get_event_loop()
        future = loop.ensure_future(callee())
        while not future.done():
            # Какие-нибудь циклические дела
        print(future.result() + ' World')
    

    或者在未来安装回调

    async def caller():
        loop = asyncio.get_event_loop()
        future = loop.ensure_future(callee())
        future.add_done_callback(lambda f: print(f.result() + ' World'))
        # какие-нибудь другие важные дела
    

    或者也许将它们收集在一个列表中并等待一切。或者不是全部,而只是将首先执行的一个,而忽略其余的。或者将未来传递给另一个协程,然后自己做其他事情。总的来说,它是“一个非常有用的锅,你可以放任何你想要的东西”。

    剩下的只是弄清楚未来与任务有何不同。在大多数情况下,它们没有什么不同。Task类是Future类的后代。asyncio.create_task()和之间唯一显着的区别loop.ensure_future()是第一个在 Python 3.7 之前不存在。

    总结一下:Task是分配给事件循环的一个任务,要执行coroutine,也是一个Future,是Task未来某个时间执行的结果。

    • 16

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    是否可以在 C++ 中继承类 <---> 结构?

    • 2 个回答
  • Marko Smith

    这种神经网络架构适合文本分类吗?

    • 1 个回答
  • Marko Smith

    为什么分配的工作方式不同?

    • 3 个回答
  • Marko Smith

    控制台中的光标坐标

    • 1 个回答
  • Marko Smith

    如何在 C++ 中删除类的实例?

    • 4 个回答
  • Marko Smith

    点是否属于线段的问题

    • 2 个回答
  • Marko Smith

    json结构错误

    • 1 个回答
  • Marko Smith

    ServiceWorker 中的“获取”事件

    • 1 个回答
  • Marko Smith

    c ++控制台应用程序exe文件[重复]

    • 1 个回答
  • Marko Smith

    按多列从sql表中选择

    • 1 个回答
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Suvitruf - Andrei Apanasik 什么是空? 2020-08-21 01:48:09 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5