How to terminate loop.run_in_executor with ProcessPoolExecutor gracefully? How to terminate loop.run_in_executor with ProcessPoolExecutor gracefully? python-3.x python-3.x

How to terminate loop.run_in_executor with ProcessPoolExecutor gracefully?


You can use the initializer parameter of ProcessPoolExecutor to install a handler for SIGINT in each process.

Update:On Unix, when the process is created, it becomes a member of the process group of its parent. If you are generating the SIGINT with Ctrl+C, then the signal is being sent to the entire process group.

import asyncioimport concurrent.futuresimport osimport signalimport sysfrom time import sleepdef handler(signum, frame):    print('SIGINT for PID=', os.getpid())    sys.exit(0)def init():        signal.signal(signal.SIGINT, handler)def blocking_task():    sleep(15)async def main():    exe = concurrent.futures.ProcessPoolExecutor(max_workers=5, initializer=init)    loop = asyncio.get_event_loop()    tasks = [loop.run_in_executor(exe, blocking_task) for i in range(2)]    await asyncio.gather(*tasks)if __name__ == "__main__":    try:        asyncio.run(main())    except KeyboardInterrupt:        print('ctrl + c')

Ctrl-C shortly after start:

^CSIGINT for PID= 59942SIGINT for PID= 59943SIGINT for PID= 59941SIGINT for PID= 59945SIGINT for PID= 59944ctrl + c