使用Python编写Linux系统守护进程实例
作者:junjie 发布时间:2022-06-09 16:50:52
守护进程(daemon)是指在UNIX或其他多任务操作系统中在后台执行的电脑程序,并不会接受电脑用户的直接操控。此类程序会被以进程的形式初始化。通常,守护进程没有任何存在的父进程(即PPID=1),且在UNIX系统进程层级中直接位于init之下。守护进程程序通常通过如下方法使自己成为守护进程:对一个子进程调用fork,然后使其父进程立即终止,使得这个子进程能在init下运行。– *
守护进程区别于普通用户登陆系统后运行的进程,它是直接由系统初始化,和系统用户没有关系,而用户开启的进程依存与用户连接的终端,当终端退出或断开,进程也会随着终止。
来看一下我Linux试验机的进程状态:
[root@home tmp]# ping www.baidu.com > /dev/null &
[1] 2759
[root@home tmp]# pstree -p
systemd(1)-+-agetty(157)
|-agetty(163)
|-avahi-daemon(129)---avahi-daemon(134)
|-avahi-dnsconfd(125)
|-crond(121)
|-dbus-daemon(130)
|-haveged(128)
|-ifplugd(126)
|-nginx(226)---nginx(227)
|-ntpd(223)
|-python(2727)
|-rngd(124)
|-sshd(216)---sshd(2683)---bash(2690)-+-ping(2759)
| `-pstree(2760)
|-systemd(2687)---(sd-pam)(2688)
|-systemd-journal(76)
|-systemd-logind(127)
|-systemd-udevd(89)
`-wpa_supplicant(153)
可以看到,当前有一个ping程序在后台运行,如果如断开连接,再次去登陆,ping程序是已经终止了的。也就是说,普通进程,和用户会话相关,那么,如何去编写一个和用户会话无关,一直运行在后台的进程呢?大家可能注意到了上面pid为2727的python,如果只是正常打开python,它应该是运行在bash下的,而这里却直接运行在systemd下,实际上,它是一个守护进程,来看一下python编写linux守护进程的简单实现:
#!/usr/bin/env python
import os
import signal
import time
logfile="/tmp/daemon.log"
pid=os.fork()
#exit parent process
if pid: exit()
#get the pid of subprocess
daeid=os.getpid()
os.setsid()
os.umask(0)
os.chdir("/")
#Redirection file descriptor
fd=open("/dev/null","a+")
os.dup2(fd.fileno(),0)
os.dup2(fd.fileno(),1)
os.dup2(fd.fileno(),2)
fd.close()
log=open(logfile,'a')
log.write('Daemon start up at %s\n'%(time.strftime('%Y:%m:%d',time.localtime(time.time()))))
log.close()
def reload(a,b):
log=open(logfile,'a')
log.write('Daemon reload at %s\n'%(time.strftime('%Y:%m:%d',time.localtime(time.time()))))
log.close()
while True:
signal.signal(signal.SIGHUP,reload)
time.sleep(2)
要点是利用linux中,当一个进程的父进程终止是,系统会接管这个进程,让init成为这个进程的父进程,这时候这个进程就成为了一个守护进程。需要注意的是,通过setsid,umask和chdir做工作目录设置、关闭文件描述符、设置文件创建掩码等操作。把上面的代码保存起来,给于运行权限,并用python打开,就会看到有一个新的守护进程在运行,并且能够处理系统发送的SIGHUP信号。
以上程序仅用来测试,仅能够处理系统SIGHUP信号,请使用kill pid结束进程。


猜你喜欢
- 概要:本文主要描述XHTML中相对定位和绝对定位各自的本质、用法、区别和两者之间的关系。以及使用CSS的Left、Right、Top、Bot
- 1、泛型是什么Go1.18增加了对泛型的支持,泛型是一种独立于使用的特定类型编写代码的方式。现在可以编写函数和类型适用于一组类型集合的任何一
- 最近,我喜欢上了XML编程,但又苦于它的美观程度又不够,找了许多书才搞定。 &n
- 当你可能前一秒设置了MySQL密码,出去吃个饭拿个快递的功夫可能就忘记密码了......这时我们该慌吗????不用慌兄弟们,我来解决你们忘记
- 当使用PHP在MySQL中编写查询时,它的适用性将基于MySQL本身进行检查。所以使用MySQL提供的默认日期和时间格式,即'YYY
- 首先是抓包,使用scapy模块,sniff()函数 在其中参数为本地文件路径时,操作为打开本地文件若参数为BPF过滤规则和回调函数,则进行S
- 说明: 本文的自动更新功能使用的项目为 electron-vue 脚手架搭建一个默认项目。 参考的文章如下:electron-vue 中文文
- 目录一、 文件的操作1.1创建文件1.2写入数据1.3读数据1.4 2读数据1.5读写数据1.6删除文件1.7写入文件1.8读取图片1.9备
- 我们在前面已经分别介绍了如何在spring Boot中使用JPA以及如何在Spring Boot中输出REST资源。那么关于数据库访问还有一
- 在给一个 App 做 API,从服务器端的 MySQL 取出数据,然后生成 JSON。数据中有个字段叫 content,里面保存了文章内容,
- 1、利用File Watchersgoland->Preferences->搜索框内输入 file watchers->选
- DataFrame对象本质上是带有行列索引的二维矩阵,所以欲对DataFrame对象进行转置操作,需要交换行列索引,同时使二维矩阵转置。首先
- Form表单的功能自动生成HTML表单元素检查表单数据的合法性如果验证错误,重新显示表单(数据不会重置)数据类型转换(字符类型的数据转换成相
- 推荐idea最新激活码:最新Idea激活码永久激活(最新测试有效)https://www.jb51.net/article/178193.h
- 一个例子让你彻底明白原型对象和原型链开篇之前对js中的原型链和原型对象有所了解,每当别人问我什么是原型链和原型对象时,我总是用很官方(其实自
- 想要在准备查询混合数据库系统时将SQL Server转换为 XQuery 和进行反向转换吗?了解如何开发 Web 服务来从SQL Serve
- 在python的类中会使用到“self”,本文主要是谈谈类中的self和变量的关系。先看示例代码I。
- 本文实例讲述了Python高级编程之消息队列(Queue)与进程池(Pool)。分享给大家供大家参考,具体如下:Queue消息队列1.创建i
- 1. 问题描述输入一个字符串然后对其进行逆序输出第一种方式:字符串切片第二种方式:使用循环转换然后逆序输出比如:输入字符串'hell
- 带农历的JavaScript日期时间,增加了农历使这款代码更具实用性,很不错,不但有农历,而且还可以显示民国计年,可以判断显示闰月、闰年等,