Reputation: 5387
I am using PYZMQ and it seems I cannot catch SIGTERM anymore. How do I do that for a graceful handling of SIGTERM ?
Below is the code snippet:
from time import sleep
from signal import signal, SIGTERM, SIGINT
from threading import Lock, Thread
try:
import cPickle as pickle
except ImportError:
import pickle
import zmq
zmq_poller = None
class server(Thread, object):
def __init__(self, transport):
self.context = zmq.Context()
self.zmq_socket = self.context.socket(zmq.PULL)
self.zmq_socket.setsockopt(zmq.RCVTIMEO, 2000)
self.zmq_socket.bind(transport)
self.keep_running = True
Thread.__init__(self)
def process_data(self, data):
data = self.decode(data)
def decode(self, data):
return pickle.loads(data)
def run(self):
while self.keep_running:
try:
data = self.zmq_socket.recv()
self.process_data(data)
except zmq.error.Again:
pass
except zmq.error as e:
print e
def stop(self):
self.keep_running = False
def handle_stop(signum=None, frame=None):
if zmq_poller:
zmq_poller.stop()
if __name__ == '__main__':
signal(SIGTERM, handle_stop)
signal(SIGINT, handle_stop)
mc = server('ipc:///tmp/abc')
zmq_poller = mc
mc.setDaemon(True)
mc.start()
mc.join()
sleep(100)
As we see, the handle_stop signal handler is not invoked if I send SIGTERM, SIGINT to the process
Upvotes: 1
Views: 882
Reputation: 3196
The reason for your problem is that your main thread is blocked on threading.Thread.join
Execution of Python signal handlers:
A Python signal handler does not get executed inside the low-level (C) signal handler. Instead, the low-level signal handler sets a flag which tells the virtual machine to execute the corresponding Python signal handler at a later point(for example at the next bytecode instruction)
…
A long-running calculation implemented purely in C (such as regular expression matching on a large body of text) may run uninterrupted for an arbitrary amount of time, regardless of any signals received. The Python signal handlers will be called when the calculation finishes.
Pre-3.3, the signal
module definitely doesn't expose the tools you'd need to fix this problem yourself. So, if you can't upgrade to 3.3, the solution is to wait on something interruptible, like a Condition
or an Event
. The child thread notifies the event right before it quits, and the main thread waits on the event before it joins the child thread.
Upvotes: 1