首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >TProcessPoolServer优雅的关闭?

TProcessPoolServer优雅的关闭?
EN

Stack Overflow用户
提问于 2012-05-21 17:29:43
回答 2查看 2.8K关注 0票数 2

--如何优雅地关闭TProcessPoolServer? --我还没有找到任何文档、示例或博客文章。到目前为止,以下是我的经历。

我是直接在命令行./ thrift _service.py上运行我的节俭服务器,而不是在主管下运行。我使用python2.6和节俭0.8.0。

我最初尝试过:

代码语言:javascript
复制
server = TProcessPoolServer(processor, transport, tfactory, pfactory)
try:
    server.serve()
finally:
    server.stop()

当我发送σ--父python进程时,我在输出中看到“终止”,进程被终止,但是它的子进程是孤立的,并且继续运行。

然后我偶然发现了节约服务器测试,并试着:

代码语言:javascript
复制
import signal
def set_alarm(server):
    def clean_shutdown(signum, frame):
        for worker in server.workers:
            logging.error("Terminating worker: {0}".format(worker))
            worker.terminate()
        logging.error("Requesting server to stop()")
        try:
            server.stop()
        except (KeyboardInterrupt, SystemExit):
            pass
        except Exception as err:
            logging.exception(err)
    def logme(s, *args, **kwargs):
        logging.error(">>> {0} <<<".format(s))
        clean_shutdown(*args, **kwargs)
    signal.signal(signal.SIGALRM, clean_shutdown)
    signal.signal(signal.SIGHUP, clean_shutdown)
    signal.signal(signal.SIGINT, clean_shutdown)
    signal.signal(signal.SIGTERM, lambda x, y: logme("SIGTERM", x, y))
server = TProcessPoolServer(processor, transport, tfactory, pfactory)
set_alarm(server)
server.serve()

当我向父python进程发送σ、sigalrm、sighup或sigint时,服务器将停止接受连接,但进程不会终止。

在输出中我看到:

代码语言:javascript
复制
ERROR:root:>>> SIGTERM <<<
ERROR:root:Terminating worker: <Process(Process-1, started daemon)>
ERROR:root:Terminating worker: <Process(Process-2, started daemon)>
ERROR:root:Terminating worker: <Process(Process-3, started daemon)>
ERROR:root:Terminating worker: <Process(Process-4, started daemon)>
ERROR:root:Terminating worker: <Process(Process-5, started daemon)>
ERROR:root:Requesting server to stop()

这是意料之中的,但随后信号再次被捕获,进程不再处于启动状态,服务器被要求停止。这部分发生了大约十次,然后没有更多的输出。

代码语言:javascript
复制
ERROR:root:>>> SIGTERM <<<
ERROR:root:Terminating worker: <Process(Process-1, unknown daemon)>
ERROR:root:Requesting server to stop()

有时,我从多处理库中看到一个AssertionError:

代码语言:javascript
复制
Traceback (most recent call last):
  File "/path/to/thrift_service.py", line 340, in clean_shutdown
    server.stop()
  File "/usr/local/lib/python2.6/dist-packages/thrift/server/TProcessPoolServer.py", line 123, in stop
    self.stopCondition.notify()
  File "/usr/lib/python2.6/multiprocessing/synchronize.py", line 223, in notify
    assert not self._wait_semaphore.acquire(False)
AssertionError
EN

回答 2

Stack Overflow用户

发布于 2012-05-25 16:58:29

我使用信号和它公开的TProcessPoolServer为python中的postForkCallback添加了一个优雅的关机。一旦初始化,TProcessPoolServer将在每个工作进程中调用您的postForkCallback。这允许您设置信号处理程序并优雅地关闭。由于工作人员捕获了SystemExit或KeyboardInterruptException异常,您可以为SIGINT设置一个处理程序,然后在清理完调用sys.exit(0)之后,这将导致工作人员关闭。

代码语言:javascript
复制
import signal
import sys

def setupHandlers():
    signal.signal(signal.SIGINT, handleSIGINT)
    #Optionally if you want to keep the current socket connection open and working
    #tell python to make system calls non-interruptable, which is probably what you want.
    signal.siginterrupt(signal.SIGINT, False)

def handleSIGINT(sig, frame):
     #clean up state or what ever is necessary
     sys.exit(0)

server = TProcessPoolServer(processor, transport, tfactory, pfactory)
server.setPostForkCallback(setupHandlers)

#Setup handlers in main process too
setupHandlers()

#Start server
server.start()

这样,生成的每个辅助进程都会设置信号处理程序,以正确处理优雅的关机。在本例中,我为主进程设置了相同的处理程序,也为可能根据用例工作的工作人员设置了相同的处理程序,但如果需要,您可以轻松地为主进程定义不同的处理程序。请记住,处理程序将从每个进程的上下文中调用,这样您就无法在清理期间跨进程共享状态。

有关http://docs.python.org/library/signal.html做什么以及为什么需要它的更多细节,请参见signal.siginterrupt。

编辑:您将需要使用Crtl +C向所有进程发送SIGINT信号,或者如果它作为守护进程运行,则杀死所有进程的-SIGINT pids。

您可以很容易地使用ps -ppid父pid获取工人的pids。

票数 2
EN

Stack Overflow用户

发布于 2021-04-13 07:34:26

程序启动后,我记录了主进程的进程号。然后根据ps --ppid,返回主进程的子进程,然后逐个杀死它们。

我的服务的控制shell脚本的代码:

代码语言:javascript
复制
function stop
{
    SERVER_PID=`cat logs/server.pid`
    SPIDS=`ps --ppid $SERVER_PID | awk '{if ($1!="PID") print $1}'`
    kill -9 $SERVER_PID
    for PID in $SPIDS
    do
        kill -9 $PID
    done
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10689772

复制
相关文章

相似问题

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