I can't kill the program below with ctrl-C:
import asyncio
loop1 = asyncio.new_event_loop()
asyncio.set_event_loop(loop1)
loop2 = asyncio.new_event_loop()
loop1.run_forever()
However, I can kill the program below:
import asyncio
# execute this first
loop2 = asyncio.new_event_loop()
loop1 = asyncio.new_event_loop()
asyncio.set_event_loop(loop1)
loop1.run_forever()
Why?
(I'm running these in python 3.11.1, windows)
CodePudding user response:
neither of these methods is a proper way to construct an event loop, and both ways should be avoided, the official way to start an eventloop is to use asyncio.run() with a coroutine.
the behavior you are seeing is because asyncio sets the current signal handler to the file-descriptor that interrupts the last created loop using signal.set_wakeup_fd, so the interrupt signal is sent to loop 2, while loop 1 is being served by the process and isn't handling those signals the OS is sending, you can read more about the way asyncio handles keyboard interrupt in Handling Keyboard Interruption
to avoid all of these problems you should use the official way to start an event-loop, ie : asyncio.run(main())
as in the asyncio documentation and avoid creating loops yourself, otherwise you can run into all sorts of trouble. (orphaned tasks, bad file descriptors, unhandled signals, etc..) or just avoid creating more than one eventloop, and handle all the related consequences of creating a loop yourself.
Application developers should typically use the high-level asyncio functions, such as asyncio.run(), and should rarely need to reference the loop object or call its methods. This section is intended mostly for authors of lower-level code, libraries, and frameworks, who need finer control over the event loop behavior.
import asyncio
async def main():
print('Hello ...')
await asyncio.sleep(1)
print('... World!')
asyncio.run(main())