python下編寫(xiě)守護(hù)進(jìn)程

**1胶滋、編寫(xiě)守護(hù)進(jìn)程的步驟 **
創(chuàng)建守護(hù)進(jìn)程其實(shí)和c創(chuàng)建守護(hù)進(jìn)程的方式大同小異了,其實(shí)就是那么幾個(gè)步驟:

  1. 創(chuàng)建子進(jìn)程惭婿,父進(jìn)程退出
  1. 改變當(dāng)前目錄為根目錄
  2. 在子進(jìn)程中創(chuàng)建新會(huì)話
  3. 重設(shè)文件權(quán)限掩碼
  4. 子進(jìn)中創(chuàng)建孫子進(jìn)程箕昭,子進(jìn)程退出,孫子進(jìn)程成為真正的守護(hù)進(jìn)程
  5. 關(guān)閉文件描述符

2衣陶、定義一個(gè)Daemon類柄瑰,有其他人寫(xiě)好的標(biāo)準(zhǔn)類,可以直接引用

daemon_python.py
#!/usr/bin/env python
#coding:utf-8
import sys, os, time, atexitfrom signal
import SIGTERM 

class Daemon:
    """
    A generic daemon class.
    Usage: subclass the Daemon class and override the run() method
    """
    def __init__(self, pidfile, stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'):
        self.stdin = stdin
        self.stdout = stdout
        self.stderr = stderr
        self.pidfile = pidfile    
    
    def daemonize(self):
        """
        do the UNIX double-fork magic, see Stevens' "Advanced 
        Programming in the UNIX Environment" for details (ISBN 0201563177)
        http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16
        """
        try: 
            pid = os.fork() 
            if pid > 0:                
            # exit first parent
                sys.exit(0) 
        except OSError, e: 
            sys.stderr.write("fork #1 failed: %d (%s)\n" % (e.errno, e.strerror))
            sys.exit(1)       
       
        # decouple from parent environment
        os.chdir("/") 
        os.setsid() 
        os.umask(0) 

        # do second fork
        try: 
            pid = os.fork() 
            if pid > 0:                
            # exit from second parent
                sys.exit(0) 
        except OSError, e: 
            sys.stderr.write("fork #2 failed: %d (%s)\n" % (e.errno, e.strerror))
            sys.exit(1) 

        # redirect standard file descriptors
        sys.stdout.flush()
        sys.stderr.flush()
        si = file(self.stdin, 'r')
        so = file(self.stdout, 'a+')
        se = file(self.stderr, 'a+', 0)
        os.dup2(si.fileno(), sys.stdin.fileno())
        os.dup2(so.fileno(), sys.stdout.fileno())
        os.dup2(se.fileno(), sys.stderr.fileno())        
        # write pidfile
        atexit.register(self.delpid)
        pid = str(os.getpid())
        file(self.pidfile,'w+').write("%s\n" % pid)   
        
    def delpid(self):
        os.remove(self.pidfile) 
    
    def start(self):
        """
        Start the daemon
        """
        # Check for a pidfile to see if the daemon already runs
        try:
            pf = file(self.pidfile, 'r')
            pid = int(pf.read().strip())
            pf.close()        
       except IOError:
            pid = None

        if pid:
            message = "pidfile %s already exist. Daemon already running?\n"
            sys.stderr.write(message % self.pidfile)
            sys.exit(1)        
        
        # Start the daemon
        self.daemonize()
        self.run()    
  
    def stop(self):
        """
        Stop the daemon
        """
        # Get the pid from the pidfile
        try:
            pf = file(self.pidfile, 'r')
            pid = int(pf.read().strip())
            pf.close()       
       except IOError:
            pid = None

        if not pid:
            message = "pidfile %s does not exist. Daemon not running?\n"
            sys.stderr.write(message % self.pidfile)           
            return 

        try:           
            while 1:
                os.kill(pid, SIGTERM)
                time.sleep(0.1)        
        except OSError, err:
            err = str(err)           
            if err.find("No such process") > 0:               
                if os.path.exists(self.pidfile):
                    os.remove(self.pidfile)           
                else:               
                    print str(err)
                sys.exit(1)    
    
    def restart(self):
        """
        Restart the daemon
        """
        self.stop()
        self.start()   
    
    def run(self):
        """
        You should override this method when you subclass Daemon. It will be called after the process has been
        daemonized by start() or restart().
        """

**3剪况、寫(xiě)一個(gè)測(cè)試的守護(hù)進(jìn)程教沾,每隔兩秒向文件中寫(xiě)入數(shù)據(jù) **

test.py
#!/usr/bin/env python
#coding:utf-8
import sys, os, time, atexitfrom signal
import SIGTERM 

class Daemon:
    """
    A generic daemon class.
    Usage: subclass the Daemon class and override the run() method
    """
    def __init__(self, pidfile, stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'):
        self.stdin = stdin
        self.stdout = stdout
        self.stderr = stderr
        self.pidfile = pidfile    
    
    def daemonize(self):
        """
        do the UNIX double-fork magic, see Stevens' "Advanced 
        Programming in the UNIX Environment" for details (ISBN 0201563177)
        http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16
        """
        try: 
            pid = os.fork() 
            if pid > 0:                
            # exit first parent
                sys.exit(0) 
        except OSError, e: 
            sys.stderr.write("fork #1 failed: %d (%s)\n" % (e.errno, e.strerror))
            sys.exit(1)       
       
        # decouple from parent environment
        os.chdir("/") 
        os.setsid() 
        os.umask(0) 

        # do second fork
        try: 
            pid = os.fork() 
            if pid > 0:                
            # exit from second parent
                sys.exit(0) 
        except OSError, e: 
            sys.stderr.write("fork #2 failed: %d (%s)\n" % (e.errno, e.strerror))
            sys.exit(1) 

        # redirect standard file descriptors
        sys.stdout.flush()
        sys.stderr.flush()
        si = file(self.stdin, 'r')
        so = file(self.stdout, 'a+')
        se = file(self.stderr, 'a+', 0)
        os.dup2(si.fileno(), sys.stdin.fileno())
        os.dup2(so.fileno(), sys.stdout.fileno())
        os.dup2(se.fileno(), sys.stderr.fileno())        
        # write pidfile
        atexit.register(self.delpid)
        pid = str(os.getpid())
        file(self.pidfile,'w+').write("%s\n" % pid)   
        
    def delpid(self):
        os.remove(self.pidfile) 
    
    def start(self):
        """
        Start the daemon
        """
        # Check for a pidfile to see if the daemon already runs
        try:
            pf = file(self.pidfile, 'r')
            pid = int(pf.read().strip())
            pf.close()        
       except IOError:
            pid = None

        if pid:
            message = "pidfile %s already exist. Daemon already running?\n"
            sys.stderr.write(message % self.pidfile)
            sys.exit(1)        
        
        # Start the daemon
        self.daemonize()
        self.run()    
  
    def stop(self):
        """
        Stop the daemon
        """
        # Get the pid from the pidfile
        try:
            pf = file(self.pidfile, 'r')
            pid = int(pf.read().strip())
            pf.close()       
       except IOError:
            pid = None

        if not pid:
            message = "pidfile %s does not exist. Daemon not running?\n"
            sys.stderr.write(message % self.pidfile)           
            return 

        try:           
            while 1:
                os.kill(pid, SIGTERM)
                time.sleep(0.1)        
        except OSError, err:
            err = str(err)           
            if err.find("No such process") > 0:               
                if os.path.exists(self.pidfile):
                    os.remove(self.pidfile)           
                else:               
                    print str(err)
                sys.exit(1)    
    
    def restart(self):
        """
        Restart the daemon
        """
        self.stop()
        self.start()   
    
    def run(self):
        """
        You should override this method when you subclass Daemon. It will be called after the process has been
        daemonized by start() or restart().
        """

是不是很簡(jiǎn)單,你們自己也動(dòng)手試一下吧译断。
這里用到的命令行解析函數(shù)OptionParser()授翻,大家可以自己去查下,這個(gè)函數(shù)功能很強(qiáng)大

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末孙咪,一起剝皮案震驚了整個(gè)濱河市堪唐,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌翎蹈,老刑警劉巖淮菠,帶你破解...
    沈念sama閱讀 219,539評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異荤堪,居然都是意外死亡合陵,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評(píng)論 3 396
  • 文/潘曉璐 我一進(jìn)店門(mén)澄阳,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)拥知,“玉大人,你說(shuō)我怎么就攤上這事碎赢【偈” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,871評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵揩抡,是天一觀的道長(zhǎng)户侥。 經(jīng)常有香客問(wèn)我,道長(zhǎng)峦嗤,這世上最難降的妖魔是什么蕊唐? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,963評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮烁设,結(jié)果婚禮上替梨,老公的妹妹穿的比我還像新娘钓试。我一直安慰自己,他們只是感情好副瀑,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,984評(píng)論 6 393
  • 文/花漫 我一把揭開(kāi)白布弓熏。 她就那樣靜靜地躺著,像睡著了一般糠睡。 火紅的嫁衣襯著肌膚如雪挽鞠。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,763評(píng)論 1 307
  • 那天狈孔,我揣著相機(jī)與錄音信认,去河邊找鬼。 笑死均抽,一個(gè)胖子當(dāng)著我的面吹牛嫁赏,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播油挥,決...
    沈念sama閱讀 40,468評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼潦蝇,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了深寥?” 一聲冷哼從身側(cè)響起攘乒,我...
    開(kāi)封第一講書(shū)人閱讀 39,357評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎翩迈,沒(méi)想到半個(gè)月后持灰,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體盔夜,經(jīng)...
    沈念sama閱讀 45,850評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡负饲,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,002評(píng)論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了喂链。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片返十。...
    茶點(diǎn)故事閱讀 40,144評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖椭微,靈堂內(nèi)的尸體忽然破棺而出洞坑,到底是詐尸還是另有隱情,我是刑警寧澤蝇率,帶...
    沈念sama閱讀 35,823評(píng)論 5 346
  • 正文 年R本政府宣布迟杂,位于F島的核電站,受9級(jí)特大地震影響本慕,放射性物質(zhì)發(fā)生泄漏排拷。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,483評(píng)論 3 331
  • 文/蒙蒙 一锅尘、第九天 我趴在偏房一處隱蔽的房頂上張望监氢。 院中可真熱鬧,春花似錦、人聲如沸浪腐。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,026評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)议街。三九已至泽谨,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間傍睹,已是汗流浹背隔盛。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,150評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留拾稳,地道東北人吮炕。 一個(gè)月前我還...
    沈念sama閱讀 48,415評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像访得,于是被迫代替她去往敵國(guó)和親龙亲。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,092評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容