使用Python編寫Linux系統(tǒng)守護(hù)進(jìn)程實(shí)例
守護(hù)進(jìn)程(daemon)是指在UNIX或其他多任務(wù)操作系統(tǒng)中在后臺執(zhí)行的電腦程序,并不會接受電腦用戶的直接操控。此類程序會被以進(jìn)程的形式初始化。通常,守護(hù)進(jìn)程沒有任何存在的父進(jìn)程(即PPID=1),且在UNIX系統(tǒng)進(jìn)程層級中直接位于init之下。守護(hù)進(jìn)程程序通常通過如下方法使自己成為守護(hù)進(jìn)程:對一個(gè)子進(jìn)程調(diào)用fork,然后使其父進(jìn)程立即終止,使得這個(gè)子進(jìn)程能在init下運(yùn)行。–維基百科
守護(hù)進(jìn)程區(qū)別于普通用戶登陸系統(tǒng)后運(yùn)行的進(jìn)程,它是直接由系統(tǒng)初始化,和系統(tǒng)用戶沒有關(guān)系,而用戶開啟的進(jìn)程依存與用戶連接的終端,當(dāng)終端退出或斷開,進(jìn)程也會隨著終止。
來看一下我Linux試驗(yàn)機(jī)的進(jìn)程狀態(tài):
[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)
可以看到,當(dāng)前有一個(gè)ping程序在后臺運(yùn)行,如果如斷開連接,再次去登陸,ping程序是已經(jīng)終止了的。也就是說,普通進(jìn)程,和用戶會話相關(guān),那么,如何去編寫一個(gè)和用戶會話無關(guān),一直運(yùn)行在后臺的進(jìn)程呢?大家可能注意到了上面pid為2727的python,如果只是正常打開python,它應(yīng)該是運(yùn)行在bash下的,而這里卻直接運(yùn)行在systemd下,實(shí)際上,它是一個(gè)守護(hù)進(jìn)程,來看一下python編寫linux守護(hù)進(jìn)程的簡單實(shí)現(xiàn):
#!/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)
要點(diǎn)是利用linux中,當(dāng)一個(gè)進(jìn)程的父進(jìn)程終止是,系統(tǒng)會接管這個(gè)進(jìn)程,讓init成為這個(gè)進(jìn)程的父進(jìn)程,這時(shí)候這個(gè)進(jìn)程就成為了一個(gè)守護(hù)進(jìn)程。需要注意的是,通過setsid,umask和chdir做工作目錄設(shè)置、關(guān)閉文件描述符、設(shè)置文件創(chuàng)建掩碼等操作。把上面的代碼保存起來,給于運(yùn)行權(quán)限,并用python打開,就會看到有一個(gè)新的守護(hù)進(jìn)程在運(yùn)行,并且能夠處理系統(tǒng)發(fā)送的SIGHUP信號。
以上程序僅用來測試,僅能夠處理系統(tǒng)SIGHUP信號,請使用kill pid結(jié)束進(jìn)程。
- Python 創(chuàng)建守護(hù)進(jìn)程的示例
- Python守護(hù)進(jìn)程實(shí)現(xiàn)過程詳解
- python并發(fā)編程多進(jìn)程之守護(hù)進(jìn)程原理解析
- python實(shí)現(xiàn)守護(hù)進(jìn)程、守護(hù)線程、守護(hù)非守護(hù)并行
- python使用fork實(shí)現(xiàn)守護(hù)進(jìn)程的方法
- Python如何實(shí)現(xiàn)守護(hù)進(jìn)程的方法示例
- Python守護(hù)進(jìn)程和腳本單例運(yùn)行詳解
- python daemon守護(hù)進(jìn)程實(shí)現(xiàn)
- python實(shí)現(xiàn)的守護(hù)進(jìn)程(Daemon)用法實(shí)例
- python 如何設(shè)置守護(hù)進(jìn)程
相關(guān)文章
講解Python的Scrapy爬蟲框架使用代理進(jìn)行采集的方法
這篇文章主要介紹了講解Python的Scrapy爬蟲框架使用代理進(jìn)行采集的方法,并介紹了隨機(jī)使用預(yù)先設(shè)好的user-agent來進(jìn)行爬取的用法,需要的朋友可以參考下2016-02-02
對python中的os.getpid()和os.fork()函數(shù)詳解
今天小編就為大家分享一篇對python中的os.getpid()和os.fork()函數(shù)詳解,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-08-08
Python?Numpy布爾數(shù)組在數(shù)據(jù)分析中的應(yīng)用小結(jié)
本文深入探討了Python的Numpy庫中的布爾數(shù)組功能,介紹了布爾運(yùn)算、布爾索引的使用方法,并通過示例展示了如何在數(shù)據(jù)分析中利用布爾數(shù)組進(jìn)行數(shù)據(jù)篩選和處理,感興趣的朋友一起看看吧2024-09-09

