2016-01-14 2 views
3

Я пытаюсь написать класс для обработки сигналов с использованием модуля python signal. Причина наличия класса - избежать использования глобальных переменных. Это код, который я придумал, но, к сожалению, не работает:Обработчик сигналов внутри класса

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, никогда не вызывается.

Итак, мой вопрос: возможно ли обрабатывать сигнал внутри класса или использовать глобальные переменные?

ответ

4

Чтобы ответить на ваш вопрос, я создал следующий простой код:

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>) 

Итак, я думаю, что ответ «Да», это возможность обрабатывать сигнал внутри класса.

Что касается того, почему вы код не работает, извините, я понятия не имею.

0

У меня есть аналогичная проблема с toti08, ссылаясь на setVmeHandler (self), и выяснилось, что обработчик должен иметь соответствующие параметры i.e. (self, signum, frame).

Смежные вопросы