我正在使用PYZMQ,似乎我不能再抓住SIGTERM了。为了优雅地处理SIGTERM,我该怎么做?
以下是代码段:
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)
如我所见,如果我向进程发送SIGTERM,SIGINT,则不会调用handle_stop信号处理程序
答案 0 :(得分:1)
您遇到问题的原因是您的主要帖子在threading.Thread.join
Execution of Python signal handlers上被阻止了:
Python信号处理程序不会在低级(C)信号处理程序中执行。相反,低级信号处理程序设置一个标志,告诉虚拟机稍后执行相应的Python信号处理程序(例如,在下一个字节码指令处)
...
纯粹在C中实现的长时间运行计算(例如在大量文本上进行正则表达式匹配)可以在任意时间内不间断地运行,无论接收到任何信号。计算完成后将调用Python信号处理程序。
3.3之前的版本,signal
模块绝对不会公开您自己解决此问题所需的工具。因此,如果您无法升级到3.3,则解决方案是等待可中断的内容,例如Condition
或Event
。子线程在退出之前立即通知事件,主线程在它加入子线程之前等待事件。