与asyncio一起运行阻塞和取消阻塞任务

2024-05-03 05:12:49 发布

您现在位置:Python中文网/ 问答频道 /正文

我想同时异步运行阻塞和取消阻塞任务。显然,有必要使用run_in_executor方法来阻止来自asyncio的任务。以下是我的示例代码:

import asyncio
import concurrent.futures
import datetime
import time


def blocking():
    print("Enter to blocking()", datetime.datetime.now().time())
    time.sleep(2)
    print("Exited from blocking()", datetime.datetime.now().time())


async def waiter():
    print("Enter to waiter()", datetime.datetime.now().time())
    await asyncio.sleep(3)
    print("Exit from waiter()", datetime.datetime.now().time())


async def asynchronous(loop):
    print("Create tasks", datetime.datetime.now().time())
    task_1 = asyncio.create_task(waiter())

    executor = concurrent.futures.ThreadPoolExecutor(max_workers=3)
    task_2 = loop.run_in_executor(executor, blocking)

    tasks = [task_1, task_2]
    print("Tasks are created", datetime.datetime.now().time())
    await asyncio.wait(tasks)


if __name__ == "__main__":
    try:
        loop = asyncio.get_event_loop()
        loop.run_until_complete(asynchronous(loop))
    except (OSError) as exc:
        sys.exit('Exception: ' + str(exc))

我应该使用相同的事件循环来阻止run_in_executor中的任务,还是必须使用另一个事件循环?为了使代码异步工作,我应该在代码中更改什么?谢谢


Tags: run代码inimportloopasynciotaskdatetime
1条回答
网友
1楼 · 发布于 2024-05-03 05:12:49

您必须使用相同的循环。循环委托给执行器,执行器运行的任务是事件循环的独立线程。因此,您不必担心阻塞任务会阻塞事件循环。如果使用单独的循环,事件循环中的异步函数将无法等待阻止在新循环中运行的函数的结果

事件循环通过创建表示执行者任务的未来来管理这一点。然后,它在其中一个执行器线程中运行阻塞任务,当执行器任务返回未来的结果时,将设置并将控制返回到事件循环中的等待函数(如果有)

相关问题 更多 >