我正在尝试使用signal python模块编写一个处理信号的类。有一个类的原因是避免使用全局变量。这是我提出的代码,但不幸的是它没有用:
import signal
import constants
class SignalHandler (object):
def __init__(self):
self.counter = 0
self.break = False
self.vmeHandlerInstalled = False
def setVmeHandler(self):
self.vmeBufferFile = open('/dev/vme_shared_memory0', 'rb')
self.vmeHandlerInstalled = True
signal.signal(signal.SIGUSR1, self.traceHandler)
signal.siginterrupt(signal.SIGUSR1, False)
#...some other stuff...
def setBreakHandler(self):
signal.signal(signal.SIGINT, self.newBreakHandler)
signal.siginterrupt(signal.SIGINT, False)
def newBreakHandler(self, signum, frame):
self.removeVMEHandler()
self.break = True
def traceHandler(self, signum, frame):
self.counter += constants.Count
def removeVMEHandler(self):
if not self.vmeHandlerInstalled: return
if self.vmeBufferFile is None: return
signal.signal(signal.SIGUSR1, signal.SIG_DFL)
self.vmeHandlerInstalled = False
在主程序中,我按以下方式使用此类:
def run():
sigHandler = SignalHandler()
sigHandler.setBreakHandler()
sigHandler.setVmeHandler()
while not sigHandler.break:
#....do some stuff
if sigHandler.counter >= constants.Count:
#...do some stuff
此解决方案无法正常工作,因为signal.SIGUSR1
方法中安装的setVmeHandler
处理程序似乎永远不会被调用。
所以我的问题是:是否可以处理类中的信号或者我是否应该使用全局变量?
答案 0 :(得分:8)
为了回答你的问题,我创建了以下简单代码:
import signal
import time
class ABC(object):
def setup(self):
signal.signal(signal.SIGUSR1, self.catch)
signal.siginterrupt(signal.SIGUSR1, False)
def catch(self, signum, frame):
print("xxxx", self, signum, frame)
abc = ABC()
abc.setup()
time.sleep(20)
如果我运行它:
python ./test.py
然后在另一个窗口发送USR1信号:
kill -USR1 4357
该过程打印出预期的消息:
('xxxx', <__main__.ABC object at 0x7fada09c6190>, 10, <frame object at 0x7fada0aaf050>)
所以我认为答案是肯定的,它可以处理班级内的信号。
至于为什么你的代码不起作用,抱歉,我不知道。
答案 1 :(得分:1)
我遇到类似于toti08的问题,指的是setVmeHandler(self),并发现处理程序必须具有匹配的参数,即(self,signum,frame)。