jiamo
jiamo

Reputation: 1456

signal handler in mulitprocess.process class , can't get class's val

Use this example , I want capture signal .and print var in class.

import signal
import time
import multiprocessing

class test(multiprocessing.Process):
    def __init__(self):
        super(test,self).__init__()
        self.a = []

    def handle(self,sig,frm):
        print "in hander  selfid    " , id(self)
        print "in handler self.a    " , self.a
        print "in handler self.a id " , id(self.a)

    def run(self):

        self.a = [1 ,2] 
        print "in run selfid        " , id(self)
        print "in run self.a id     " , self.a 
        print "in run self.a id is  " , id(self.a)
        while 1:
            time.sleep(10)

test_1 = test()

signal.signal(signal.SIGALRM,test_1.handle)
test_1.run()
time.sleep(2)

signal.alarm(1)

Use ubunut12.04 python 2.7 The answer is like :

python test.py

in run selfid         139880313607120
in run self.a id      [1, 2]
in run self.a id is   139880313975872
in hander  selfid     139880313607120
in handler self.a     []
in handler self.a id  139880313580432

while I expect the answer:

in handler self.a is [1,2]

Putting signal.signal(signal.SIGALRM,test_1.handle) in self.__init__ doesn't work too.

I use this method to get: when the parent was killed by SIGTERM. the signal handler defun in parent , will iterate it's child process list to kill it. And register it in __init__ fun. the child list get in run() fun like the example. I print the id of self. when the handler is called , self is same . however , self.a is different . As the print show , run was called first , then handler .so self.a should be same ? So , what's problem here ?

Upvotes: 1

Views: 2437

Answers (1)

Dan Kruchinin
Dan Kruchinin

Reputation: 3045

If you try to print PID of the process that catches and handles SIGALRM, you'll see that it's a parent process, not the child:

    ...
    def handle(self,sig,fem):
        print "in handler pid: ", os.getpid()

...
signal.signal(signal.SIGALRM,test_1.handle)
test_1.start()
print "Parent PID: ", os.getpid()
print "Child PID: ", test_1.pid
...

Output:

Parent PID:  3137
Child PID:  3138
...
in handler pid:  3137 <-- parent
...

You need to modify your code so that:

  1. The signal handler is set inside the child process
  2. The signal is sent to child process
class test(multiprocessing.Process):
    ...
    def handle(self,sig,fem):
        ...

    def run(self):
        signal.signal(signal.SIGALRM, self.handle)
        ...

...
test_1.start()
time.sleep(2)

os.kill(test_1.pid, signal.SIGALRM)

Upvotes: 2

Related Questions