Home > Software design >  Send Ctrl C to asyncio Task
Send Ctrl C to asyncio Task

Time:05-26

So I have two tasks running until complete in my event loop. I want to handle KeyboardInterrupt when running those Tasks and send the same signal to the Tasks in the event loop when receiving it.

 loop = asyncio.get_event_loop()
    try:
        loop.run_until_complete(asyncio.gather(
            task_1(),
            task_2()
        ))
    except KeyboardInterrupt:
        pass
        # Here I want to send sigterm to the tasks in event loop

Is there any way to do this?

CodePudding user response:

Use asyncio.run() instead. asyncio.run() cancels all tasks/futures when receiving exceptions.

asyncio.gather() would then cancel the tanks when itself is cancelled. You may capture asyncio.CancelledError around asyncio.sleep() to see. Discard it would keep the task running.

async def task_1():
    try:
        await asyncio.sleep(10)
    except asyncio.CancelledError as ex:
        print('task1', type(ex))
        raise


async def task_2():
    try:
        await asyncio.sleep(10)
    except asyncio.CancelledError as ex:
        print('task2', type(ex))
        raise


async def main():
    await asyncio.gather(task_1(), task_2())


if __name__ == '__main__':
    asyncio.run(main())

Otherwise, you need to keep references to tasks, cancel them, and re-run the event loop to propagate CancelledError, like what asynio.run() do under the hood.

  • Related