为什么我需要在这个队列示例中取消任务? [英] Why i need cancel tasks in this queue example?

查看:68
本文介绍了为什么我需要在这个队列示例中取消任务?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好吧,我正在查看 Python 文档以研究我的工作.我是 Python 和编程的新手,我也不太了解异步操作等编程概念.

Well I am looking into python documentation for study for my work. I am new to python and also programming, I also do not understand concepts of programming like async operations very well.

我使用 Fedora 29 和 Python 3.7.3 作为队列和 lib asyncio 的尝试示例.

I usign Fedora 29 with Python 3.7.3 for try examples of queue and the lib asyncio.

按照下面的队列和异步操作示例:

Follow the example of queue and async operations below:

import asyncio
import random
import time


async def worker(name, queue):
    while True:
        # Get a "work item" out of the queue.
        sleep_for = await queue.get()

        # Sleep for the "sleep_for" seconds.
        await asyncio.sleep(sleep_for)

        # Notify the queue that the "work item" has been processed.
        queue.task_done()

        print(f'{name} has slept for {sleep_for:.2f} seconds')


async def main():
    # Create a queue that we will use to store our "workload".
    queue = asyncio.Queue()

    # Generate random timings and put them into the queue.
    total_sleep_time = 0
    for _ in range(20):
        sleep_for = random.uniform(0.05, 1.0)
        total_sleep_time += sleep_for
        queue.put_nowait(sleep_for)

    # Create three worker tasks to process the queue concurrently.
    tasks = []
    for i in range(3):
        task = asyncio.create_task(worker(f'worker-{i}', queue))
        tasks.append(task)

    # Wait until the queue is fully processed.
    started_at = time.monotonic()
    await queue.join()
    total_slept_for = time.monotonic() - started_at

    # Cancel our worker tasks.
    for task in tasks:
        task.cancel()
    # Wait until all worker tasks are cancelled.
    await asyncio.gather(*tasks, return_exceptions=True)

    print('====')
    print(f'3 workers slept in parallel for {total_slept_for:.2f} seconds')
    print(f'total expected sleep time: {total_sleep_time:.2f} seconds')

asyncio.run(main())

为什么在这个例子中我需要取消任务?为什么我可以排除这部分代码

Why in this example I need cancel the tasks? Why I can exclude this part of code

# Cancel our worker tasks.
    for task in tasks:
        task.cancel()
    # Wait until all worker tasks are cancelled.
    await asyncio.gather(*tasks, return_exceptions=True)

并且示例工作正常吗?

推荐答案

为什么在这个例子中我需要取消任务?

Why in this example i need cancel the tasks?

因为否则它们将无限期地挂起,等待队列中永远不会到达的新项目.在那个特定的示例中,无论如何您都将退出事件循环,因此它们挂起"并没有什么害处,但是如果您将其作为实用程序函数的一部分这样做,则会造成协程泄漏.

Because they will otherwise remain hanging indefinitely, waiting for a new item in the queue that will never arrive. In that particular example you are exiting the event loop anyway, so there's no harm from them "hanging", but if you did that as part of a utility function, you would create a coroutine leak.

换句话说,取消工作人员会告诉他们退出,因为不再需要他们的服务,并且需要确保与他们相关的资源得到释放.

In other words, canceling the workers tells them to exit because their services are no longer necessary, and is needed to ensure that resources associated with them get freed.

这篇关于为什么我需要在这个队列示例中取消任务?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆