Python processes stop responding to SIGTERM / SIGINT after restart

I am having a weird problem with some python processes started using a watchdog process.

The watchdog process is written in python and is the parent, and has a start_child (name) function that uses subprocess.Popen to open the child process. The Popen object is written so that the watchdog can monitor the process using poll () and, in the end, terminate its terminate () if necessary. If the child dies unexpectedly, the watchdog again calls start_child (name) and writes a new Popen object.

There are 7 child processes, all of which are also pythons. If I start any of the children manually, I can send SIGTERM or SIGINT using kill and get the expected results (the process ends).

However, when starting from the watchdog process, the child ends only after the FIRST signal . When the watchdog restarts the child, the new child process no longer responds to SIGTERM or SIGINT. I do not know what causes this.

watchdog.py

class watchdog:
    # <snip> various init stuff

    def start(self):
        self.running = true

        kids = ['app1', 'app2', 'app3', 'app4', 'app5', 'app6', 'app7']
        self.processes = {}

        for kid in kids:
            self.start_child(kid)

        self.thread = threading.Thread(target=self._monitor)
        self.thread.start()

        while self.running:
            time.sleep(10)

    def start_child(self, name):
        try:
            proc = subprocess.Popen(name)
            self.processes[name] = proc
        except:
            print "oh no"
        else:
            print "started child ok"

    def _monitor(self):
        while self.running:
            time.sleep(1)
            if self.running:
                for kid, proc in self.processes.iteritems():
                    if proc.poll() is not None: # process ended
                        self.start_child(kid)

So what happens, watchdog.start () starts all 7 processes, and if I send any SIGTERM process, it ends, and the monitor thread starts it again. However, if I then submit a new SIGTERM process, it ignores it.

kill -15 . ?

+3
2

: http://blogs.gentoo.org/agaffney/2005/03/18/python_sucks, Python , ( , ).

sigprocmask, ctypes. "" , .

__init__:

libc = ctypes.cdll.LoadLibrary("libc.so")
mask = '\x00' * 17 # 16 byte empty mask + null terminator 
libc.sigprocmask(3, mask, None) # '3' on FreeBSD is the value for SIG_SETMASK
+5

Python, ctypes? :

import signal
for sig in range(1, signal.NSIG):
    try:
        signal.signal(sig, signal.SIG_DFL)
    except RuntimeError:
        pass

RuntimeError , SIGKILL, .

0

Source: https://habr.com/ru/post/1712717/


All Articles