python进程在等待信号量时,如何在收到SIGTERM后优雅地退出?

python进程在等待信号量时,如何在收到SIGTERM后优雅地退出?,python,python-multiprocessing,Python,Python Multiprocessing,我有一个Python进程,它使用多处理模块生成了另外5个Python进程。让我们调用父进程P0和其他进程P1-P5。要求是,如果我们向P0发送SIGTERM,它应该首先关闭P1到P5,然后自行退出 捕获点是P1和P5正在等待信号量。因此,当我向这些进程发送SIGTERM时,它们调用信号处理程序并退出。但由于它们正在等待信号量,因此会抛出异常。是否有任何方法可以在退出之前捕获该异常,以便P0到P5可以顺利退出 回溯: Traceback (most recent call last): Fil

我有一个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()

您可以安装一个信号处理程序,它抛出一个异常,然后在子流程中捕获该异常,以优雅地处理退出

下面是一个脚本示例,它在子进程中的信号量中等待,并在发送
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异常,该异常可以在流程内部处理。

您使用的Python版本是什么?P1和P5实际进行了什么特定的调用,使它们等待信号量?你能包括回溯吗?一个简单的代码示例来重现你的问题会很好。我使用的是Python 2.7.8 P1到P5,它们试图访问一个跨进程共享的队列,并且对队列的访问使用信号量进行保护。类似这样的代码示例:sem.acquire()item=q.get()sem.release()