python daemon守护进程实现


Posted in Python onAugust 27, 2016

假如写一段服务端程序,如果ctrl+c退出或者关闭终端,那么服务端程序就会退出,于是就想着让这个程序成为守护进程,像httpd一样,一直在后端运行,不会受终端影响。
守护进程英文为daemon,像httpd,mysqld,最后一个字母d其实就是表示daemon的意思。

守护进程的编写步骤:

1、fork子进程,然后父进程退出,此时子进程会被init进程接管。
2、修改子进程的工作目录,创建新进程组合新会话,修改umask。
3、子进程再次fork一个进程,这个进程可以称为孙子进程,然后子进程退出。
4、重定向孙子进程的标准输入流,标准输出流,标准错误到/dev/null
完成上面的4个步骤,那么最终的孙子进程就称为守护进程,先看下代码,后面分析下步骤的原因。

#!/usr/bin/env python
#coding=utf8
def createDaemon():
  import os, sys, time
  #产生子进程,而后父进程退出
  try:
    pid = os.fork()
    if pid > 0:sys.exit(0)
  except OSError,error:
    print 'fork'
    sys.exit(1)
 
  #修改子进程工作目录
  os.chdir("/")
  #创建新的会话,子进程成为会话的首进程
  os.setsid()
  #修改工作目录的umask
  os.umask(0)
 
  #创建孙子进程,而后子进程退出
  try:
    pid = os.fork()
    if pid > 0:
      print "Daemon PID %d"%pid
      sys.exit(0)
  except OSError,error:
    print "fork"
    sys.exit(1)
  run()
 
 
def ping():
  import os
  os.system('ping www.baidu.com >/dev/nul')
 
def run():
  while True:
    import time,threading
    fd = open('/home/ping.log', 'a')
    fd.write("start time---------:%s\n"%time.ctime())
    fd.flush()
    t=threading.Thread(target=ping,args=())
    t.start()
    time.sleep(3)
    fd.write("end of time--------:%s\n"%time.ctime())
    fd.flush()
  fd.close()
 
if __name__=='__main__':
  createDaemon()

1、fork子进程,父进程退出
通常,我们执行服务端程序的时候都会通过终端连接到服务器,成功连接后会加载shell环境,终端盒shell都是进程,shell进程是终端进程的子进程,通过ps命令可以很容易的查看到,在这个shell环境下一开始执行的程序都是shell进程的子进程,自然会受到shell进程的影响,在程序里fork子进程后,父进程退出,对于shell进程来说,这个父进程就算执行完毕,而产生的子进程会被init进程接管,从而也就脱离了终端控制。
2.修改子进程的工作目录
子进程在创建的时候会继承父进程的工作目录,如果执行的程序是在U盘里面,就会导致U盘不能卸载。
3.创建新会话
使用setsid后,子进程就会成为新会话的首进程,子进程会成为新进程组的组长进程,子进程没有控制终端。
4.修改umask
由于umask会屏蔽权限,所有设定为0,这样可以避免读写文件时碰到权限问题
5.fork孙子进程,子进程退出
经过上面几个步骤后,子进程会成为新的进程组老大,可以重新申请打开终端,为了避免这个问题,fork孙子进程处理,
6.重定向孙子进程的标准输入流,标准输出流,标准错误流到/dev/null
因为是守护进程,本身已经脱离了终端,那么标准输入流,标准输入流,标准错误流就没有什么意义了,所以都转向到/dev/null,就是丢弃的意思

我们来运行一个这个程序,看看效果

python daemon守护进程实现

从上图可以看出这个脚本程序已经放入后台,只能使用killall方式来结束掉,
接下来我们去看下记录的日志

python daemon守护进程实现

Python 相关文章推荐
天翼开放平台免费短信验证码接口使用实例
Dec 18 Python
Python入门篇之列表和元组
Oct 17 Python
Python File readlines() 使用方法
Mar 19 Python
Django中更改默认数据库为mysql的方法示例
Dec 05 Python
python实现对任意大小图片均匀切割的示例
Dec 05 Python
python获取点击的坐标画图形的方法
Jul 09 Python
详解用python生成随机数的几种方法
Aug 04 Python
Python列表如何更新值
May 27 Python
快速解释如何使用pandas的inplace参数的使用
Jul 23 Python
python中编写函数并调用的知识点总结
Jan 13 Python
python process模块的使用简介
May 14 Python
Python+Appium实现自动抢微信红包
May 21 Python
Python+微信接口实现运维报警
Aug 27 #Python
python实现获取Ip归属地等信息
Aug 27 #Python
python简单实现获取当前时间
Aug 27 #Python
python使用psutil模块获取系统状态
Aug 27 #Python
Django Highcharts制作图表
Aug 27 #Python
Python连接DB2数据库
Aug 27 #Python
使用python绘制常用的图表
Aug 27 #Python
You might like
星际争霸秘籍
2020/03/04 星际争霸
JQuery 学习笔记 选择器之二
2009/07/23 Javascript
Extjs学习笔记之一 初识Extjs之MessageBox
2010/01/07 Javascript
jQuery 处理表单元素的代码
2010/02/15 Javascript
JQuery入门——用映射方式绑定不同事件应用示例
2013/02/05 Javascript
javascript history对象(历史记录)使用方法(实现浏览器前进后退)
2014/01/07 Javascript
详解js中构造流程图的核心技术JsPlumb(2)
2015/12/08 Javascript
JavaScipt中栈的实现方法
2016/02/17 Javascript
jquery模拟多级复选框效果的简单实例
2016/06/08 Javascript
jQuery解析返回的xml和json方法详解
2017/01/05 Javascript
jQuery选择器实例应用
2017/01/05 Javascript
Vue v2.4中新增的$attrs及$listeners属性使用教程
2018/01/08 Javascript
简单的Vue SSR的示例代码
2018/01/12 Javascript
JS实现基于拖拽改变物体大小的方法
2018/01/23 Javascript
使用Sonarqube扫描Javascript代码的示例
2018/12/26 Javascript
一些你可能不熟悉的JS知识点总结
2019/03/15 Javascript
微信小程序实现单个卡片左滑显示按钮并防止上下滑动干扰功能
2019/12/06 Javascript
JavaScript对象原型链原理解析
2020/01/22 Javascript
JS 图片压缩原理与实现方法详解
2020/04/29 Javascript
Python机器学习之SVM支持向量机
2017/12/27 Python
python语言元素知识点详解
2019/05/15 Python
浅谈django channels 路由误导
2020/05/28 Python
Python绘制组合图的示例
2020/09/18 Python
世界第一冲浪品牌:O’Neill
2016/08/30 全球购物
世界上最大的隐形眼镜商店:1-800 Contacts
2018/11/03 全球购物
北美女性服装零售连锁店:maurices
2019/06/12 全球购物
运动会开幕式邀请函
2014/01/22 职场文书
公务员培训自我鉴定
2014/02/01 职场文书
个人贷款收入证明
2014/10/26 职场文书
万能检讨书
2015/01/27 职场文书
财务个人年度总结范文
2015/02/26 职场文书
台风停课通知
2015/04/24 职场文书
《小蝌蚪找妈妈》教学反思
2016/02/23 职场文书
MySQL系列之七 MySQL存储引擎
2021/07/02 MySQL
「我的青春恋爱物语果然有问题。-妄言录-」第20卷封面公开
2022/03/21 日漫
ubuntu20.04虚拟机无法上网的问题及解决
2022/12/24 Servers