如何终止 asyncio 协程(不是 First_completed 案例)

How to kill an asyncio coroutine (not First_completed case)

有一个例子:main协程创建了需要很长时间才能完成的协程,这意味着FIRST_COMPLETED case is unreachable。问题:考虑到 await asyncio.wait(tasks) 行阻塞了它自身下的所有内容,如何访问未决期货集?

import asyncio

async def worker(i):
    #some big work
    await asyncio.sleep(100000)

async def main():
    tasks = [asyncio.create_task(worker(i), name=str(i)) for i in range(5)]
    done, pending = await asyncio.wait(tasks) #or asyncio.as_completed(tasks, return_when=FIRST_COMPLETED) no matter
    # everything below is unreachable until tasks are in process
    # we want to kill certain task
    for future in pending:
        if future.get_name == "4":
            future.close()

loop = asyncio.get_event_loop()
loop.run_until_complete(main())

如何避免等待阻塞并杀死某些协程?例如 4?

您可以创建另一个任务来监控您的任务:

async def monitor(tasks):
    # monitor the state of tasks and cancel some
    while not all(t.done() for t in tasks):
        for t in tasks:
            if not t.done() and t.get_name() == "4":
                t.cancel()
            # ...
        # give the tasks some time to make progress
        await asyncio.sleep(1)

async def main():
    tasks = [asyncio.create_task(worker(i), name=str(i)) for i in range(5)]
    tasks.append(asyncio.create_task(monitor(tasks[:])))
    done, pending = await asyncio.wait(tasks)
    # ...