代码之家  ›  专栏  ›  技术社区  ›  jsstuball

什么时候使用loop.add信号处理程序?

  •  1
  • jsstuball  · 技术社区  · 5 年前

    我注意到Asyncio库有一个 loop.add_signal_handler(signum, callback, *args) 方法。

    到目前为止,我只是在主文件中使用 signals 我的异步代码模块如下:

    signal.signal(signal.SIGHUP, callback)
    
    async def main():
        ...
    

    这是我的疏忽吗?

    1 回复  |  直到 5 年前
        1
  •  2
  •   user4815162342    5 年前

    这个 add_signal_handler documentation 是稀疏的,但看着 the source ,与 signal.signal 那是 添加信号处理程序 将确保信号 唤醒事件循环 并允许循环调用信号处理程序以及其他排队回调和可运行协程。

    到目前为止,我只是使用信号模块[…]在主文件中捕获Unix信号,这是我的疏忽吗?

    这取决于信号处理程序正在做什么。打印消息或更新全局是可以的,但如果它以任何方式调用与Asyncio相关的任何内容,则很可能是一种疏忽。信号可以(几乎)在任何时候传递,包括在异步回调、协程执行期间,甚至在异步自己记账期间。

    例如,实现 asyncio.Queue 自由地假设对队列的访问是单线程和不可重入的。向队列添加内容的信号处理程序,使用 q.put_nowait() 如果它中断了正在进行的 QuffiNoaIt() 在同一队列中。类似于经典的线程竞争条件,在分配过程中中断 _unfinished_tasks 很可能导致它只递增一次而不是两次。

    异步代码是 designed 对于 合作的 多任务处理,其中函数可以挂起的点定义为 await 以及相关关键字。这个 添加信号处理程序 函数确保您的信号处理程序在这样的时刻被调用,并且您可以像实现任何其他异步回调一样自由地实现它。