类中的信号处理程序

时间:2016-01-14 09:59:55

标签: python signals

我正在尝试使用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处理程序似乎永远不会被调用。

所以我的问题是:是否可以处理类中的信号或者我是否应该使用全局变量?

2 个答案:

答案 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)。