简体   繁体   English

调用第二个 new_event_loop() 后 ctrl-C 不起作用

[英]ctrl-C doesn't work after calling second new_event_loop()

I can't kill the program below with ctrl-C:我无法用 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) (我在 python 3.11.1,windows 中运行这些)

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.这两种方法都不是构建事件循环的正确方法,应该避免这两种方法,启动事件循环的官方方法是将asyncio.run()与协程一起使用。

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您看到的行为是因为 asyncio 将当前信号处理程序设置为使用signal.set_wakeup_fd中断最后创建的循环的文件描述符,因此中断信号被发送到循环 2,而循环 1 正在由进程提供服务并且不是在处理操作系统发送的那些信号时,您可以在Handling Keyboard Interruption中阅读更多关于 asyncio 处理键盘中断的方式

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.为了避免所有这些问题,您应该使用官方方式启动事件循环,即:asyncio文档中的asyncio.run(main())并避免自己创建循环,否则您会遇到各种麻烦。 (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.应用程序开发人员通常应使用高级异步函数,例如 asyncio.run(),并且很少需要引用循环 object 或调用其方法。 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())

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM