RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1600912
Accepted
Иван
Иван
Asked:2024-11-26 22:11:52 +0000 UTC2024-11-26 22:11:52 +0000 UTC 2024-11-26 22:11:52 +0000 UTC

是否可以在 asyncio 中进行两次超时等待?

  • 772

我正在学习 asyncio 并需要解决以下问题。如果协程完成时间超过 3 秒,则需要完成任务。其余任务必须在10秒后完成(程序总运行时间为10秒)。像这样的代码。

async def some_coro(time):
    print(f"Корутина {asyncio.current_task().get_name()} запустилась")
    try:
       await asyncio.sleep(time)
       print(f"Корутина {asyncio.current_task().get_name()} завершилась")
    except asyncio.CancelledError:
       print(f"Корутина {asyncio.current_task().get_name()} отменена")
    

async def wait_10():
    print('начало отсчета 10 сек')
    await asyncio.sleep(10)
    print ('10 сек прошло. Завершаем все задачи')
    for task in asyncio.all_tasks():
        try:
            task.cancel()
        except asyncio.CancelledError:
            pass

async def main():
   tasks = [asyncio.create_task(some_coro(12)), asyncio.create_task(some_coro(2)), asyncio.create_task(some_coro(15))]
    #await asyncio.create_task(wait_10())
   await asyncio.wait(tasks, timeout=5)

asyncio.run(main())  

如果我只运行一个 asyncio.wait(tasks, timeout=5)。然后简单地在 5 秒后取消未完成的任务(但没有 10 秒的通用计数器)如果我添加等待 asyncio.create_task(wait_10()),那么似乎 asyncio.wait 中的超时“不再起作用”,并且这对我来说就是全部任务在 10 秒后完成,而不是在 5 秒超时后完成。首先,我想亲自了解为什么会发生这种情况?其次,是否可以制作“两个独立”的计数器?我觉得我缺少一些异步基础知识,想弄清楚。提前致谢。

python
  • 1 1 个回答
  • 25 Views

1 个回答

  • Voted
  1. Best Answer
    CrazyElf
    2024-11-26T23:06:52Z2024-11-26T23:06:52Z

    如果我只运行一个asyncio.wait(tasks, timeout=5),那么未完成的任务将在 5 秒后被取消

    不,不是任务被取消,而是任务在等待asyncio.wait。返回两个列表:已完成的任务和未完成的任务。

    如果您希望timeout稍后取消任务,请使用asyncio.wait_for,此函数将取消运行时间超过 的任务timeout。

    如果我添加await asyncio.create_task(wait_10()),那么感觉就像timeout它asyncio.wait“不再工作”,并且我的所有任务都在 10 秒后完成,而不是在 5 秒超时后完成。

    当然,这是事实,因为你首先等待任务完成wait_10,然后下一个等待任务才开始工作,而此时你已经杀死了任务中的所有任务wait_10。顺便说一句,您不加区别地杀死那里的所有任务,包括任务本身wait_10和任何处于活动状态的任务,包括当前任务await。

    这是一个代码示例,可能会让事情变得更清楚。只是我main()在这里启动它的方式有点不同,因为我通过Jupyter Notebook,你的启动方法在那里不起作用。

    是的,同时我纠正了错误,被调用函数的错误名称等。

    import asyncio
    
    async def main_task(time):
        print(f"Корутина {asyncio.current_task().get_name()} запустилась")
        try:
           await asyncio.sleep(time)
           print(f"Корутина {asyncio.current_task().get_name()} завершилась")
        except asyncio.CancelledError:
           print(f"Корутина {asyncio.current_task().get_name()} отменена")
        
    
    async def wait_10():
        print('начало отсчета 10 сек')
        await asyncio.sleep(10)
        print ('10 сек прошло. Завершаем все задачи')
        for task in asyncio.all_tasks():
            try:
                name = task.get_name()
                if task.get_name().startswith('MT'):
                    print(f'Отменяем задачу {name}')
                    task.cancel()
            except asyncio.CancelledError:
                pass
    
    def show_stats(tasks):
        print(f'Запущено задач: {sum(not t.done() for t in tasks)}')
    
    async def main():
        tasks = [asyncio.create_task(main_task(12), name='MT12'), 
                 asyncio.create_task(main_task(2), name='MT2'), 
                 asyncio.create_task(main_task(15), name='MT15')]
        kill_task = asyncio.create_task(wait_10())
        show_stats(tasks)
        await kill_task
        show_stats(tasks)
        await asyncio.wait(tasks)
        print('Завершаем работу')
    
    await main()
    

    结论:

    Запущено задач: 3
    Корутина MT12 запустилась
    Корутина MT2 запустилась
    Корутина MT15 запустилась
    начало отсчета 10 сек
    Корутина MT2 завершилась
    10 сек прошло. Завершаем все задачи
    Отменяем задачу MT15
    Отменяем задачу MT12
    Корутина MT15 отменена
    Корутина MT12 отменена
    Запущено задач: 0
    Завершаем работу
    

    我给任务命名是为了区分那些应该强制结束的任务和其他最好不要管的任务。

    新增运行任务统计。到最后,等待任务就已经这样了,以防万一。至此,所有的任务都已经强行完成了。

    • 2

相关问题

  • 是否可以以某种方式自定义 QTabWidget?

  • telebot.anihelper.ApiException 错误

  • Python。检查一个数字是否是 3 的幂。输出 无

  • 解析多个响应

  • 交换两个数组的元素,以便它们的新内容也反转

Sidebar

Stats

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

    我看不懂措辞

    • 1 个回答
  • Marko Smith

    请求的模块“del”不提供名为“default”的导出

    • 3 个回答
  • Marko Smith

    "!+tab" 在 HTML 的 vs 代码中不起作用

    • 5 个回答
  • Marko Smith

    我正在尝试解决“猜词”的问题。Python

    • 2 个回答
  • Marko Smith

    可以使用哪些命令将当前指针移动到指定的提交而不更改工作目录中的文件?

    • 1 个回答
  • Marko Smith

    Python解析野莓

    • 1 个回答
  • Marko Smith

    问题:“警告:检查最新版本的 pip 时出错。”

    • 2 个回答
  • Marko Smith

    帮助编写一个用值填充变量的循环。解决这个问题

    • 2 个回答
  • Marko Smith

    尽管依赖数组为空,但在渲染上调用了 2 次 useEffect

    • 2 个回答
  • Marko Smith

    数据不通过 Telegram.WebApp.sendData 发送

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +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