在等待信号量的同时接收SIGTERM后,python进程如何正常退出?

时间:2014-10-16 22:05:42

标签: python python-multiprocessing

我有一个Python进程,使用多处理模块生成其他5个Python进程。让我们调用父进程P0和其他P1-P5。要求是,如果我们将SIGTERM发送到P0,它应该首先关闭P1到P5然后退出自己。

捕获是P1,P5正在等待信号量。因此,当我将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 个答案:

答案 0 :(得分:13)

您可以安装一个抛出异常的信号处理程序,然后在子进程中捕获该异常以正常处理退出。

这是一个脚本示例,它在子进程中等待信号量,并在发送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异常。