3

I have the following code

def signal_handler(self,signum,frame):
            self.kill_received = True
            print "signal received",signum
            self.condition.set()

def mainFunc(self):
     while not self.kill_received:
          * do something *

It has been observed when actual signals are raised, signal_handler prints the signum, but the loop goes on. I even tried printing the self.kill_received value inside the loop. It showed false, even after signal handler execution.

Also, if I put a print of self.kill_received within the signal handler, I can see it has become True. But it isn't reflected outside. Even if I call a function from the signal handler, it reflects the modified value of kill_received. It is as if there are two parallel address space or something for the main process and signal handlers( not sure as I am new to Python and its internal workings are not known)

Could someone explain this behaviour of instance variables in Python? I tried using 'global kill_received' but it gives "not defined" errors..

Here is the entire code on request

 class CreateData(multiprocessing.Process):

     def __init__(self, recv_queue, reportName, reportDirectory, condition, chunkSize = 100, maxReportSize = 350, isChunked = True):
            multiprocessing.Process.__init__(self)
            self.reportName = reportName
            self.reportDirectory = reportDirectory
            self.recv_queue = recv_queue

            self.chunkSize = chunkSize * 1024 * 1024
            self.maxReportSize = maxReportSize * 1024 * 1024
            self.current_chunk_size = 0
            self.isChunked = isChunked
            self.chunk_suffix = 0


            # Flow control attributes
            signal.signal(signal.SIGTERM,self.signal_handler)
            signal.signal(signal.SIGUSR1,self.signal_handler)
            self.kill_received = False
            self.condition = condition

    def signal_handler(self,signum,frame):
            self.kill_received = True
            print "signal received",signum
            self.condition.set()


    def run(self):
            self.makeReport(True)

    def makeReport(self,isChunked):
             swing=20*(self.chunkSize/100)
             up_swing=(self.chunkSize+swing)  #upper swing size
             low_swing=(self.chunkSize-swing) #lower swing size

             while(not self.kill_received):
             #{
                 self.funcTest()     
             #}

EDIT This problem occurs only when the signal is initiated from a function within this class. If I do an os.kill(child_pid,signal) from main process, it gets handled as expected.

But when I perform os.kill(os.ppid(),signal) from a function in this class, only the printing within signal handler happens. Variables are not set.

Vivek
  • 259
  • 2
  • 16
  • Can you show the code where you register the signal handler? – Hampus Nilsson May 17 '12 at 13:04
  • signal.signal(signal.SIGUSR1,self.signal_handler) this is inside __init__ – Vivek May 17 '12 at 13:05
  • Could you post the code for the whole class, or possibly the whole module? – bpgergo May 17 '12 at 13:06
  • question edited to add whole module – Vivek May 17 '12 at 13:11
  • def makeReport, is that supposed to be inside CreateData? And the loop inside it, shouldn't there be a *self.* before kill_received? – XORcist May 17 '12 at 13:20
  • yeah sorry it was there. i had modified for testing the "global" thing. and yeah makeReport is part of CreateData.. – Vivek May 17 '12 at 13:22
  • possibly related http://stackoverflow.com/questions/9916301/error-with-multiprocessing-atexit-and-global-data – mgilson May 17 '12 at 13:22
  • the problem mentioned in the URL above is about using signal handlers to process keyboard interrupt, which will not work normally. keyboard interrupt causes exception. here my signal handler is invoked properly. only the setting of variables isn't working fine. sorry. I don't see the relation.. – Vivek May 17 '12 at 13:26
  • Based on my limited experience with these things -- signals aren't properly handled within multiprocessing. (Of course, I would love to be wrong about this) – mgilson May 17 '12 at 13:26
  • hmm i shall give a try without the multiprocessing context. but even then that doesn't solve my problems :( – Vivek May 17 '12 at 13:27
  • @Vivek, raising KeyboardInterrupt is merely the default action taken when your program recieves SIGINT. In that link, I tried to handle the SIGINT via signals as well as try/except ... nothing worked. But again, I'm not an expert on handling signals in python (or anywhere else) so I would love to be proven wrong by someone who knows more than I do. – mgilson May 17 '12 at 13:28
  • from what i read i understood that python raises KeyboardInterrupt internally before SIGINT reaches our process. hence my statement. I guess no need to deviate from topic here. :) – Vivek May 17 '12 at 13:45

0 Answers0