12

我有一个 Python 进程,它使用多处理模块生成 5 个其他 Python 进程。我们称父进程为 P0,其他进程为 P1-P5。要求是,如果我们向 P0 发送 SIGTERM,它应该先关闭 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()
4

1 回答 1

15

您可以安装一个信号处理程序,该处理程序会引发异常,然后在子进程中捕获该异常以优雅地处理退出。

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

于 2014-10-17T03:13:11.300 回答