让进程安全地退出
2016-03-21 19:47
232 查看
终止一个进程有很多方法(咱只说linux环境):前台运行的进程,如果没有提供退出功能,我们通常会Ctrl+C进行终止;后台或守护进程,如果也没有提供退出命令啥的,咱通常会kill掉;此外还有类似关机或重启之类的特殊情况,也会导致进程终止。
无论哪种方法,最终都是通过向进程传递信号量的方式进行终止。只是不同的方式发送的信号也不同:比如Ctrl+C发送的是SIGINT,kill和killall发送的是SIGTERM,kill -9发送的是SIGKILL,等等。
有些信号可以在程序中捕获,针对进行特殊处理;而有些则手动捕获不了或不能忽略,只能服从命令。
对于那些可以捕获到的终止类信号(如SIGTERM、SIGHUP、SIGINT等),就如同家长向正在玩仙剑的孩子说道:“玩儿一下午了,别玩了。”
如果碰到顽皮的,那么很可能就当作耳边风了——捕获到信号后选择不终止进程;
如果孩子还算听话,那么就赶紧把游戏存个档退出了——捕获到信号后做好收尾工作,然后终止进程(安全退出,推荐);
有的则图省事直接退出——不捕获信号或不做特殊处理,直接终止进程(大部分人都这么做,不推荐);
如果碰到的是个严厉的家长,二话不说直接上前把游戏关掉,这下孩子傻眼了“我擦,还没存档!!!”——接收到了不可被忽略的终止信号
另外还有一点需要注意,针对关机和重启的情况,是由操作系统按PID正序逐个发送SIGTERM,通知大家“做好准备,要关机了”,随后(n秒后)会下最后通谍——SIGKILL。对于子进程来说,父进程由于PID小,会先收到SIGTERM,收到后会立即向子进程发SIGKILL结束子进程。这样很可能会造成子进程接收不到操作系统发的SIGTERM,还未进行收尾工作就被终止。所以,还是尽量在主进程做收尾工作,或者主进程收到SIGTERM后主动向子进程发送SIGTERM(我是这么想的,未验证 -.-)。
---------------------------------------------------我是分割线------------------------------------------------------------
附录:
网上的一段示例代码(Python)
[python] view
plain copy
print?
#!/usr/bin/env python
import time
import signal
import sys
NEEDEXIT=False
def SignalHandler(sig, id):
global NEEDEXIT
if sig == signal.SIGUSR1:
print 'received signal USR1'
elif sig == signal.SIGHUP:
print 'received signal HUP'
elif sig == signal.SIGTERM:
print 'received SIGTERM, shutting down'
NEEDEXIT = True
signal.signal(signal.SIGUSR1, SignalHandler)
signal.signal(signal.SIGHUP, SignalHandler)
signal.signal(signal.SIGTERM, SignalHandler)
while 1:
if NEEDEXIT:
sys.exit()
time.sleep(1)
参考资料:
http://hi.baidu.com/wuhy1213/blog/item/13f040066843225b0308818b.html
http://bbs.chinaunix.net/thread-99933-1-1.html
http://hi.baidu.com/syqust/blog/item/cb1fae01e8aa641a1c958321.html
http://bbs.chinaunix.net/thread-2197309-1-1.html
无论哪种方法,最终都是通过向进程传递信号量的方式进行终止。只是不同的方式发送的信号也不同:比如Ctrl+C发送的是SIGINT,kill和killall发送的是SIGTERM,kill -9发送的是SIGKILL,等等。
有些信号可以在程序中捕获,针对进行特殊处理;而有些则手动捕获不了或不能忽略,只能服从命令。
对于那些可以捕获到的终止类信号(如SIGTERM、SIGHUP、SIGINT等),就如同家长向正在玩仙剑的孩子说道:“玩儿一下午了,别玩了。”
如果碰到顽皮的,那么很可能就当作耳边风了——捕获到信号后选择不终止进程;
如果孩子还算听话,那么就赶紧把游戏存个档退出了——捕获到信号后做好收尾工作,然后终止进程(安全退出,推荐);
有的则图省事直接退出——不捕获信号或不做特殊处理,直接终止进程(大部分人都这么做,不推荐);
如果碰到的是个严厉的家长,二话不说直接上前把游戏关掉,这下孩子傻眼了“我擦,还没存档!!!”——接收到了不可被忽略的终止信号
另外还有一点需要注意,针对关机和重启的情况,是由操作系统按PID正序逐个发送SIGTERM,通知大家“做好准备,要关机了”,随后(n秒后)会下最后通谍——SIGKILL。对于子进程来说,父进程由于PID小,会先收到SIGTERM,收到后会立即向子进程发SIGKILL结束子进程。这样很可能会造成子进程接收不到操作系统发的SIGTERM,还未进行收尾工作就被终止。所以,还是尽量在主进程做收尾工作,或者主进程收到SIGTERM后主动向子进程发送SIGTERM(我是这么想的,未验证 -.-)。
---------------------------------------------------我是分割线------------------------------------------------------------
附录:
网上的一段示例代码(Python)
[python] view
plain copy
print?
#!/usr/bin/env python
import time
import signal
import sys
NEEDEXIT=False
def SignalHandler(sig, id):
global NEEDEXIT
if sig == signal.SIGUSR1:
print 'received signal USR1'
elif sig == signal.SIGHUP:
print 'received signal HUP'
elif sig == signal.SIGTERM:
print 'received SIGTERM, shutting down'
NEEDEXIT = True
signal.signal(signal.SIGUSR1, SignalHandler)
signal.signal(signal.SIGHUP, SignalHandler)
signal.signal(signal.SIGTERM, SignalHandler)
while 1:
if NEEDEXIT:
sys.exit()
time.sleep(1)
参考资料:
http://hi.baidu.com/wuhy1213/blog/item/13f040066843225b0308818b.html
http://bbs.chinaunix.net/thread-99933-1-1.html
http://hi.baidu.com/syqust/blog/item/cb1fae01e8aa641a1c958321.html
http://bbs.chinaunix.net/thread-2197309-1-1.html
相关文章推荐
- eclipse 常用快捷键
- java语言程序设计第十版(Introduce to java) 课后习题 chapter6-13
- C语言之冒泡排序、选择排序
- 基于MVC模式的JavaWeb
- php设计模式学习系列(三)工厂模式
- iOS开发UI篇—ios应用数据存储方式(归档) :转发
- 产品开发:确定产品具体功能列表的可参考流程
- Unknown entity (Hibernate的findById方法参数必须加上包名)
- 安装和使用Visual Studio 2013并进行简单的单元测试
- ARCGIS切图:TPK文件的空间参考为地理坐标系
- 用VS测试程序
- Adobe illustrator & Photoshop 处理图片
- 在windows下搭建linux-c学习环境
- 第十讲--Oracle日志原理剖析
- 在windows下搭建linux-c学习环境
- 《HiWind企业快速开发框架实战》(0)目录及框架简介
- ABP源码分析八:Logger集成
- 排序
- android studio 使用、开发小技巧
- UTF-8编码中的BOM问题