首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在接收到SIGTERM之后,python进程如何在等待信号量时优雅地退出?

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

Stack Overflow用户
提问于 2014-10-16 22:05:42
回答 1查看 7.9K关注 0票数 12

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

问题是P1和P5在等待信号量。因此,当我向这些进程发送SIGTERM时,它们调用信号处理程序并退出。但是,由于他们在等待信号量,他们抛出一个异常。是否有任何方法在退出之前捕获该异常,以便P0 to P5可以进行优雅的退出?

回溯:

代码语言:javascript
复制
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()
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-10-17 03:13:11

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

下面是一个脚本的示例,它在子进程的信号量中等待,在发送SIGTERM时优雅地终止。

代码语言:javascript
复制
#!/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()

此脚本的示例运行如下:

代码语言:javascript
复制
$ ./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异常,该异常可以在进程内处理。

票数 15
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26414704

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档