python daemon守護(hù)進(jìn)程實(shí)現(xiàn)
假如寫(xiě)一段服務(wù)端程序,如果ctrl+c退出或者關(guān)閉終端,那么服務(wù)端程序就會(huì)退出,于是就想著讓這個(gè)程序成為守護(hù)進(jìn)程,像httpd一樣,一直在后端運(yùn)行,不會(huì)受終端影響。
守護(hù)進(jìn)程英文為daemon,像httpd,mysqld,最后一個(gè)字母d其實(shí)就是表示daemon的意思。
守護(hù)進(jìn)程的編寫(xiě)步驟:
1、fork子進(jìn)程,然后父進(jìn)程退出,此時(shí)子進(jìn)程會(huì)被init進(jìn)程接管。
2、修改子進(jìn)程的工作目錄,創(chuàng)建新進(jìn)程組合新會(huì)話(huà),修改umask。
3、子進(jìn)程再次fork一個(gè)進(jìn)程,這個(gè)進(jìn)程可以稱(chēng)為孫子進(jìn)程,然后子進(jìn)程退出。
4、重定向?qū)O子進(jìn)程的標(biāo)準(zhǔn)輸入流,標(biāo)準(zhǔn)輸出流,標(biāo)準(zhǔn)錯(cuò)誤到/dev/null
完成上面的4個(gè)步驟,那么最終的孫子進(jìn)程就稱(chēng)為守護(hù)進(jìn)程,先看下代碼,后面分析下步驟的原因。
#!/usr/bin/env python
#coding=utf8
def createDaemon():
import os, sys, time
#產(chǎn)生子進(jìn)程,而后父進(jìn)程退出
try:
pid = os.fork()
if pid > 0:sys.exit(0)
except OSError,error:
print 'fork'
sys.exit(1)
#修改子進(jìn)程工作目錄
os.chdir("/")
#創(chuàng)建新的會(huì)話(huà),子進(jìn)程成為會(huì)話(huà)的首進(jìn)程
os.setsid()
#修改工作目錄的umask
os.umask(0)
#創(chuàng)建孫子進(jìn)程,而后子進(jìn)程退出
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子進(jìn)程,父進(jìn)程退出
通常,我們執(zhí)行服務(wù)端程序的時(shí)候都會(huì)通過(guò)終端連接到服務(wù)器,成功連接后會(huì)加載shell環(huán)境,終端盒shell都是進(jìn)程,shell進(jìn)程是終端進(jìn)程的子進(jìn)程,通過(guò)ps命令可以很容易的查看到,在這個(gè)shell環(huán)境下一開(kāi)始執(zhí)行的程序都是shell進(jìn)程的子進(jìn)程,自然會(huì)受到shell進(jìn)程的影響,在程序里fork子進(jìn)程后,父進(jìn)程退出,對(duì)于shell進(jìn)程來(lái)說(shuō),這個(gè)父進(jìn)程就算執(zhí)行完畢,而產(chǎn)生的子進(jìn)程會(huì)被init進(jìn)程接管,從而也就脫離了終端控制。
2.修改子進(jìn)程的工作目錄
子進(jìn)程在創(chuàng)建的時(shí)候會(huì)繼承父進(jìn)程的工作目錄,如果執(zhí)行的程序是在U盤(pán)里面,就會(huì)導(dǎo)致U盤(pán)不能卸載。
3.創(chuàng)建新會(huì)話(huà)
使用setsid后,子進(jìn)程就會(huì)成為新會(huì)話(huà)的首進(jìn)程,子進(jìn)程會(huì)成為新進(jìn)程組的組長(zhǎng)進(jìn)程,子進(jìn)程沒(méi)有控制終端。
4.修改umask
由于umask會(huì)屏蔽權(quán)限,所有設(shè)定為0,這樣可以避免讀寫(xiě)文件時(shí)碰到權(quán)限問(wèn)題
5.fork孫子進(jìn)程,子進(jìn)程退出
經(jīng)過(guò)上面幾個(gè)步驟后,子進(jìn)程會(huì)成為新的進(jìn)程組老大,可以重新申請(qǐng)打開(kāi)終端,為了避免這個(gè)問(wèn)題,fork孫子進(jìn)程處理,
6.重定向?qū)O子進(jìn)程的標(biāo)準(zhǔn)輸入流,標(biāo)準(zhǔn)輸出流,標(biāo)準(zhǔn)錯(cuò)誤流到/dev/null
因?yàn)槭鞘刈o(hù)進(jìn)程,本身已經(jīng)脫離了終端,那么標(biāo)準(zhǔn)輸入流,標(biāo)準(zhǔn)輸入流,標(biāo)準(zhǔn)錯(cuò)誤流就沒(méi)有什么意義了,所以都轉(zhuǎn)向到/dev/null,就是丟棄的意思
我們來(lái)運(yùn)行一個(gè)這個(gè)程序,看看效果

從上圖可以看出這個(gè)腳本程序已經(jīng)放入后臺(tái),只能使用killall方式來(lái)結(jié)束掉,
接下來(lái)我們?nèi)タ聪掠涗浀娜罩?/p>

- Python全棧之進(jìn)程和守護(hù)進(jìn)程
- python 如何設(shè)置守護(hù)進(jìn)程
- Python 創(chuàng)建守護(hù)進(jìn)程的示例
- Python守護(hù)進(jìn)程實(shí)現(xiàn)過(guò)程詳解
- python實(shí)現(xiàn)守護(hù)進(jìn)程、守護(hù)線(xiàn)程、守護(hù)非守護(hù)并行
- python使用fork實(shí)現(xiàn)守護(hù)進(jìn)程的方法
- Python如何實(shí)現(xiàn)守護(hù)進(jìn)程的方法示例
- Python守護(hù)進(jìn)程用法實(shí)例分析
- Python實(shí)現(xiàn)日志備份守護(hù)進(jìn)程的示例
相關(guān)文章
python GUI庫(kù)圖形界面開(kāi)發(fā)之PyQt5打印控件QPrinter詳細(xì)使用方法與實(shí)例
這篇文章主要介紹了python GUI庫(kù)圖形界面開(kāi)發(fā)之PyQt5打印控件QPrinter詳細(xì)使用方法與實(shí)例,需要的朋友可以參考下2020-02-02
python 通過(guò)手機(jī)號(hào)識(shí)別出對(duì)應(yīng)的微信性別(實(shí)例代碼)
這篇文章主要介紹了python 通過(guò)手機(jī)號(hào)識(shí)別出對(duì)應(yīng)的微信性別,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-12-12
Python爬蟲(chóng)框架Scrapy簡(jiǎn)介
這篇文章介紹了Python爬蟲(chóng)框架Scrapy,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-06-06
Python3中對(duì)json格式數(shù)據(jù)的分析處理
這篇文章主要介紹了Python3中對(duì)json格式數(shù)據(jù)的分析處理,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-01-01
使用OpenCV對(duì)車(chē)道進(jìn)行實(shí)時(shí)檢測(cè)的實(shí)現(xiàn)示例代碼
這篇文章主要介紹了使用OpenCV對(duì)車(chē)道進(jìn)行實(shí)時(shí)檢測(cè)的實(shí)現(xiàn)示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-06-06

