python 如何优雅地退出子进程
python 如何优雅地退出子进程
主进程产生子进程,子进程进入永久循环模式。当主进程要求子进程退出时,如何能安全地退出子进程呢?
参考一些代码,我写了这个例子。运行之后,用kill pid试试。pid是主进程的pid。当然子进程的也没问题。
1)如果kill pid为子进程的pid,当所有子进程都kill掉了,主进程就关闭了。这也是我们想要的结果。
2)如果kill pid为主进程的pid,主进程向子进程发送退出信号,然后等全部子进程关闭后退出。
保证了主进程在所有子进程退出之后退出。
#-*- coding: UTF-8 -*-
# graceful_exit_event.py
# UTF-8 without BOM
#
# refer:
# http://stackoverflow.com/questions/26414704/how-does-a-python-process-exit-gracefully-after-receiving-sigterm-while-waiting?rq=1
# http://www.cnblogs.com/kaituorensheng/p/4445418.html
# init created: 2016-07-13
# last updated: 2016-07-14
#
#######################################################################
import os
import signal
import multiprocessing
class GracefulExitException(Exception):
@staticmethod
def sigterm_handler(signum, frame):
raise GracefulExitException()
pass
class GracefulExitEvent(object):
def __init__(self):
self.workers = []
self.exit_event = multiprocessing.Event()
# Use signal handler to throw exception which can be caught
# by worker process to allow graceful exit.
signal.signal(signal.SIGTERM, GracefulExitException.sigterm_handler)
pass
def reg_worker(self, wp):
self.workers.append(wp)
pass
def is_stop(self):
return self.exit_event.is_set()
def notify_stop(self):
self.exit_event.set()
def wait_all(self):
while True:
try:
for wp in self.workers:
wp.join()
print "main process(%d) exit." % os.getpid()
break
except GracefulExitException:
self.notify_stop()
print "main process(%d) got GracefulExitException." % os.getpid()
except Exception, ex:
self.notify_stop()
print "main process(%d) got unexpected Exception: %r" % (os.getpid(), ex)
break
pass
#######################################################################
def worker_proc(gee):
import sys, time
print "worker(%d) start ..." % os.getpid()
try:
while not gee.is_stop():
# do task job here
print ".",
time.sleep(1)
else:
print ""
print "worker process(%d) got exit event." % os.getpid()
print "worker process(%d) do cleanup..." % os.getpid()
time.sleep(1)
print "[%d] 3" % os.getpid()
time.sleep(1)
print "[%d] 2" % os.getpid()
time.sleep(1)
print "[%d] 1" % os.getpid()
except GracefulExitException:
print "worker(%d) got GracefulExitException" % os.getpid()
except Exception, ex:
print "Exception:", ex
finally:
print "worker(%d) exit." % os.getpid()
sys.exit(0)
if __name__ == "__main__":
import sys
print "main process(%d) start" % os.getpid()
gee = GracefulExitEvent()
# Start some workers process and run forever
for i in range(0, 10):
wp = multiprocessing.Process(target=worker_proc, args=(gee,))
wp.start()
gee.reg_worker(wp)
gee.wait_all()
sys.exit(0)
需要说明的是:
如果某个进程接受 kill pid,必须在该进程函数的最外层捕获: except GracefulExitException,
同时该进程函数内部调用捕获了 except Excetion,则必须在之前捕获GracefulExitException,
即:
(2) 必须在(3)之前。否则同时去掉(2)和(3)。
def do_some_func():
try:
time.sleep(10)
blablabla
(1) except SomeError:
# 捕获特定的异常
pass
(2) except GracefulExitException:
# 接收 kill pid
pass
(3) except: # 不建议捕获默认异常, 否则必须在此之前捕获:GracefulExitException
pass
def some_process_main(gee):
try:
while not gee.is_stop():
do_some_func()
except GracefulExitException:
# 接收到了 kill pid, 设置中止循环
gee.notify_stop()
pass
except:
pass
python 如何优雅地退出子进程的更多相关文章
- 如何优雅地退出python程序
如何优雅地退出python程序 一个单模的python程序,启动之后要能够优雅地关闭.即当用户按Ctrl+C或者kill pid的时候,程序都能从容关闭.实现起来非常简单. is_running = ...
- 情景linux--如何优雅地退出telnet
情景linux--在脚本中如何优雅地退出telnet 情景 telnet命令是TELNET协议的用户接口,它支持两种模式:命令模式和会话模式.虽然telnet支持许多命令,但大部分情况下,我们只是使用 ...
- C# Note11:如何优雅地退出WPF应用程序
前言 I should know how I am supposed to exit my application when the user clicks on the Exit menu item ...
- 从nsq中学习如何优雅的退出go 网络程序
退出运行中的程序,可以粗暴的kill -9 $PID,但这样会破坏业务的完整性,有可能一个正在在执行的逻辑半途而费,从而产生不正常的垃圾数据. 本文总结在go语言中,如何能优雅的退出网络应用,涉及的知 ...
- 如何优雅的退出/关闭/重启gunicorn进程
在工作中,会发现gunicorn启动的web服务,无论怎么使用kill -9 进程号都是无法杀死gunicorn,经过我一番百度和谷歌,发现想要删除gunicorn进程其实很简单. 1. 寻找mast ...
- 【Golang】程序如何优雅的退出?
1. 背景 项目开发过程中,随着需求的迭代,代码的发布会频繁进行,在发布过程中,如何让程序做到优雅的退出? 为什么需要优雅的退出? 你的 http 服务,监听端口没有关闭,客户的请求发过来了,但处理了 ...
- 让Python更优雅更易读(第二集)
友情链接 让Python更优雅更易读(第一集) 1.装饰器 1.1装饰器特别适合用来实现以下功能 运行时校验:在执行阶段进行特定校验,当校验通不过时终止执行. 适合原因:装饰器可以方便地在函数执行前介 ...
- [转载]Python模块学习 ---- subprocess 创建子进程
[转自]http://blog.sciencenet.cn/blog-600900-499638.html 最近,我们老大要我写一个守护者程序,对服务器进程进行守护.如果服务器不幸挂掉了,守护者能即时 ...
- 一个Python中优雅的数据分块方法
背景 看到这个标题你可能想一个分块能有什么难度?还值得细说吗,最近确实遇到一个有意思的分块函数,写法比较巧妙优雅,所以写一个分享. 日前在做需求过程中有一个对大量数据分块处理的场景,具体来说就是几十万 ...
随机推荐
- 利用 pyspider 框架抓取猫途鹰酒店信息
利用框架 pyspider 能实现快速抓取网页信息,而且代码简洁,抓取速度也不错. 环境:macOS:Python 版本:Python3. 1.首先,安装 pyspider 框架,使用pip3一键安装 ...
- [POI 2004]SZP
Description Byteotian 中央情报局 (BIA) 雇佣了许多特工. 他们每个人的工作就是监视另一名特工.Byteasar 国王需要进行一次秘密行动,所以他要挑选尽量多的信得过的特工. ...
- BZOJ4711 小奇挖矿
Description [题目背景] 小奇在喵星系使用了无限非概率驱动的采矿机,以至于在所有星球上都采出了一些矿石,现在它准备建一些矿石仓 库并把矿石运到各个仓库里. [问题描述] 喵星系有n个星球, ...
- [JSOI2008]球形空间产生器
Description 有一个球形空间产生器能够在n维空间中产生一个坚硬的球体.现在,你被困在了这个n维球体中,你只知道球 面上n+1个点的坐标,你需要以最快的速度确定这个n维球体的球心坐标,以便于摧 ...
- StopAllSounds
10月3日,在杭州市西湖景区,一只小松鼠不停地接受一道道食物,花生.玉米.饼干,可谓来者不拒,憨态可掬的模样吸引了众多围观者...Description 小松鼠开心地在树之间跳跃着,突然她停了下来 ...
- 关于非旋转treap的学习
非旋转treap的操作基于split和merge操作,其余操作和普通平衡树一样,复杂度保证方式与旋转treap差不多,都是基于一个随机的参数,这样构出的树树高为\(logn\) split 作用:将原 ...
- FFT模板(BZOJ2179)
实现了两个长度为n的大数相乘. #include <cstdio> #include <cmath> #include <complex> using namesp ...
- JavaBean实现用户登陆
本文简单讲述使用javabean实现用户登录,包括用户登录,注册和退出等. 系统结构图 2.数据库表 create table P_USER ( id VARCHAR2(50) not n ...
- Python中模块之re的功能介绍
re模块的功能介绍 1. 方法 match 从开头开始查找 方法:re.match(pattern,string,flags=0) 返回值:<class '_sre.SRE_Match'> ...
- Linux学习之CentOS(十三)-----磁盘管理之 磁盘与目录的容量(转) df 与du 命令
磁盘与目录的容量 现在我们知道磁盘的整体数据是在 superblock 区块中,但是每个各别文件的容量则在 inode 当中记载的. 那在文字接口底下该如何叫出这几个数据呢?底下就让我们来谈一谈这两个 ...