相关疑难解决方法(0)

Python asyncio.create_task() - 真的需要保留引用吗?

的文档asyncio.create_task()指出以下警告:

重要提示:保存对此函数结果的引用,以避免任务在执行过程中消失。(来源)

我的问题是:这是真的吗?

我有几个 IO 绑定的“即发即忘”任务,我想asyncio通过使用将它们提交到事件循环来同时运行这些任务asyncio.create_task()。但是,我并不真正关心协程的返回值,或者即使它们运行成功,只关心它们最终运行。一种用例是将“昂贵”计算中的数据写回 Redis 数据库。如果 Redis 可用,那就太好了。如果没有,哦,好吧,没有坏处。这就是为什么我不想/不需要await这些任务。

这是一个通用示例:

import asyncio

async def fire_and_forget_coro():
    """Some random coroutine waiting for IO to complete."""
    print('in fire_and_forget_coro()')
    await asyncio.sleep(1.0)
    print('fire_and_forget_coro() done')


async def async_main():
    """Main entry point of asyncio application."""
    print('in async_main()')
    n = 3
    for _ in range(n):
        # create_task() does not block, returns immediately.
        # Note: We do NOT save a reference to the submitted task here! …
Run Code Online (Sandbox Code Playgroud)

python task python-3.x python-asyncio

17
推荐指数
1
解决办法
4193
查看次数

为什么 asyncio 任务在打开其中的连接时会被垃圾收集?

我正在创建一个服务器,它需要在响应时发出外部请求。为了处理并发请求,我使用 Python 的asyncio库。我遵循了标准库中的一些示例。然而,我的一些任务似乎被破坏了,打印Task was destroyed but it is pending!到我的终端。经过一些调试和研究后,我发现了一个 stackoverflow 答案,它似乎解释了原因。

我在下面创建了一个最小的示例来演示这种效果。我的问题是应该以什么方式抵消这种影响?存储对任务的硬引用(例如存储asyncio.current_task()在全局变量中)可以缓解该问题。如果我将 future 包装remote_read.read()为 ,它似乎也可以正常工作await asyncio.wait_for(remote_read.read(), 5)。但我确实觉得这些解决方案很丑陋。

# run and visit http://localhost:8080/ in your browser
import asyncio
import gc

async def client_connected_cb(reader, writer):
    remote_read, remote_write = await asyncio.open_connection("google.com", 443, ssl=True)
    await remote_read.read()

async def cleanup():
    while True:
        gc.collect()
        await asyncio.sleep(1)

async def main():
    server = await asyncio.start_server(client_connected_cb, "localhost", 8080)
    await asyncio.gather(server.serve_forever(), cleanup())

asyncio.run(main())
Run Code Online (Sandbox Code Playgroud)

我在 …

python python-asyncio

7
推荐指数
1
解决办法
1942
查看次数

标签 统计

python ×2

python-asyncio ×2

python-3.x ×1

task ×1