【问题标题】:ctrl-C doesn't work after calling second new_event_loop()调用第二个 new_event_loop() 后 ctrl-C 不起作用
【发布时间】:2022-12-31 21:15:13
【问题描述】:

我无法用 ctrl-C 终止下面的程序:

import asyncio

loop1 = asyncio.new_event_loop()
asyncio.set_event_loop(loop1)

loop2 = asyncio.new_event_loop()

loop1.run_forever()

但是,我可以终止下面的程序:

import asyncio

# execute this first
loop2 = asyncio.new_event_loop()

loop1 = asyncio.new_event_loop()
asyncio.set_event_loop(loop1)

loop1.run_forever()

为什么?

(我在 python 3.11.1,windows 中运行这些)

【问题讨论】:

    标签: python python-asyncio


    【解决方案1】:

    这两种方法都不是构建事件循环的正确方法,应该避免这两种方法,启动事件循环的官方方法是使用 asyncio.run() 和协程。

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

    为避免所有这些问题,您应该使用官方方式启动事件循环,即:asyncio.run(main())asyncio documentation 中一样,并避免自己创建循环,否则您会遇到各种麻烦。 (孤立的任务、错误的文件描述符、未处理的信号等)或者只是避免创建多个事件循环,并自己处理创建循环的所有相关后果。

    应用程序开发人员通常应该使用高级异步 函数,例如 asyncio.run(),应该很少需要引用 循环对象或调用其方法。本节主要用于 对于底层代码、库和框架的作者,他们需要 更好地控制事件循环行为。

    import asyncio
    
    async def main():
        print('Hello ...')
        await asyncio.sleep(1)
        print('... World!')
    
    asyncio.run(main())
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-07-25
      • 1970-01-01
      • 2019-05-07
      • 1970-01-01
      • 1970-01-01
      • 2012-08-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多