Python 脚本中存在多个 SIGTERM 处理程序 - 谁应该调用 sys.exit()?

问题描述 投票:0回答:2

假设我有以下脚本:

import signal
import sys

class Klass:
   def __init__(self, name):
     self.name = name

     def disconnect_gracefully(*args):
         print(self.name)
         sys.exit()

     signal.signal(signal.SIGINT, disconnect_gracefully)


a = Klass("A")
b = Klass("B")

while True:
    pass

请注意,这两个类在 SIGINT 后都会正常退出。当我运行这个和 crtl-c 时,只打印“B”。

一般来说,在这种情况下,whowhat应该调用

sys.exit()
- 两种情况都应该调用吗?

python oop signals
2个回答
2
投票

signal的Python文档仅说明了多次为同一信号设置处理程序时会发生什么:

特定信号的处理程序一旦设置,就会保持安装状态,直到明确重置为止

[调用时

signal.signal
]将返回之前的信号处理程序

这似乎意味着,就像 POSIX 信号一样,一个进程一次只能有一个给定信号的处理程序。

我们可以在您的程序中添加一些语句来显示

signal.signal
返回什么(在 CPython 中):

import signal
import sys
class K:
  def __init__(self, name):
    self.name=name
    def disconnect(*args):
      print(self.name)
      sys.exit()
    self.disconnectfuncid=id(disconnect)
    self.oldsig=signal.signal(signal.SIGINT, disconnect)


>>> a=K("a")
>>> hex(a.disconnectfuncid)
'0x7fc5c1057f28'
>>> a.oldsig
<built-in function default_int_handler>
>>> signal.getsignal(signal.SIGINT)
<function K.__init__.<locals>.disconnect at 0x7fc5c1057f28>


>>> b=K("b")
>>> hex(b.disconnectfuncid)
'0x7fc5c0ed0950'
>>> b.oldsig
<function K.__init__.<locals>.disconnect at 0x7fc5c1057f28>
>>> signal.getsignal(signal.SIGINT)
<function K.__init__.<locals>.disconnect at 0x7fc5c0ed0950>


>>> while True:
...   pass
...^C b

因此,处理程序以

<built-in function default_int_handler>
开始,然后设置为
disconnect
实例中的
a
函数,然后设置为
disconnect
实例中的
b
函数,后者就是被调用的函数当信号发出时。

如果您想在收到 SIGINT 时退出,并在退出前运行多个函数,一种方法是调用以下命令(这将抑制打印回溯和

KeyboardInterrupt
消息):

 signal.signal(signal.SIGINT, lambda *args: sys.exit())

然后使用 atexit.register 注册每个函数。


0
投票

已经创建了这个要点(但这只有在到处使用或至少最终使用 register_signal_handler 时才有效)

https://gist.github.com/SuperThinking/ba07424e86308faaf2ab533a75d2bbc6

© www.soinside.com 2019 - 2024. All rights reserved.