Python进程在等待信号量时如何优雅地处理SIGTERM退出?
我有一个Python程序,它会启动5个其他的Python程序,使用的是多进程模块。我们把这个主程序叫做P0,其他的叫做P1到P5。现在的要求是,如果我们给P0发送一个SIGTERM信号,它应该先关闭P1到P5,然后自己再退出。
问题是,P1和P5正在等待信号量(semaphore)。所以当我给这些进程发送SIGTERM信号时,它们会调用信号处理程序并退出。但是因为它们在等待信号量,所以会抛出一个异常。有没有办法在退出之前捕获这个异常,这样P0到P5就可以优雅地退出呢?
错误追踪信息:
Traceback (most recent call last):
File "/usr/lib64/python2.7/multiprocessing/process.py", line 258, in _bootstrap
Traceback (most recent call last):
Process Process-2:
File "/usr/lib64/python2.7/multiprocessing/process.py", line 258, in _bootstrap
Traceback (most recent call last):
self.run()
File "/usr/lib64/python2.7/multiprocessing/process.py", line 114, in run
self._target(*self._args, **self._kwargs)
Process Process-5:
Traceback (most recent call last):
File "/usr/lib64/python2.7/multiprocessing/process.py", line 258, in _bootstrap
self.run()
File "/usr/lib64/python2.7/multiprocessing/process.py", line 114, in run
self._target(*self._args, **self._kwargs)
File "/opt/fireeye/scripts/mip/StaticAnalysisRunner.py", line 45, in run
qsem.acquire()
1 个回答
17
你可以安装一个信号处理器,当接收到特定信号时,它会抛出一个异常,然后这个异常会在子进程中被捕获,从而优雅地处理退出。
下面是一个示例脚本,它在子进程中等待一个信号量,并在收到一个 SIGTERM
信号时优雅地终止。
#!/usr/bin/env python
import signal
import time
import multiprocessing
class GracefulExit(Exception):
pass
def signal_handler(signum, frame):
raise GracefulExit()
def subprocess_function():
try:
sem = multiprocessing.Semaphore()
print "Acquiring semaphore"
sem.acquire()
print "Semaphore acquired"
print "Blocking on semaphore - waiting for SIGTERM"
sem.acquire()
except GracefulExit:
print "Subprocess exiting gracefully"
if __name__ == "__main__":
# Use signal handler to throw exception which can be caught to allow
# graceful exit.
signal.signal(signal.SIGTERM, signal_handler)
# Start a subprocess and wait for it to terminate.
p = multiprocessing.Process(target=subprocess_function)
p.start()
print "Subprocess pid: %d" % p.pid
p.join()
这个脚本的一个示例运行结果如下:
$ ./test.py
Subprocess pid: 7546
Acquiring semaphore
Semaphore acquired
Blocking on semaphore - waiting for SIGTERM
----> Use another shell to kill -TERM 7546
Subprocess exiting gracefully
从子进程中没有错误追踪信息,流程显示子进程以优雅的方式退出。这是因为 SIGTERM
信号被子进程的信号处理器捕获,处理器抛出了一个普通的 Python 异常,这个异常可以在进程内部被处理。