2016-02-29 72 views
1

(我的理解有關於同一主題的SO現有的一些問題,我看了上面的答案。這些問題的答案是好的,但我仍然有一些不清楚。) 最近我碰到了一塊來到的Python在unix系統中創建守護進程:sample code 而一塊,我想談:瞭解Python代碼

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) 

所以這個過程是:

  1. 創建當前進程的一個分支,並殺死父進程。所以在這種情況下分叉進程1現在是一個孤兒。從父
  2. 解耦environment-- 我們爲什麼要這麼做?這是否意味着通過設置分叉進程1的sid,我們可以隔離分叉進程?此時分叉進程1擁有自己的進程組和會話(相當於它的pid),這意味着它是會話的領導者,這意味着有可能獲得新的控制終端。
  3. 叉再次和殺分叉過程1.分叉過程2現在也孤兒。它絕對不是會議的領導者(分叉過程1)。它不會與原始父進程環境共享任何內容。
  4. 做輸入/輸出/ ERR重定向。

所以我的理解正確有關創建守護進程的進程?還有些人所說的「這樣可以防止殭屍進程」在SO question爲什麼這段代碼甚至與殭屍進程?父將被殺死,以便該進程受init監控,是不是「守護進程」意味着什麼?

有些人還提到一次應該給我們一個很好的守護進程。任何這樣的例子?任何一個例子(系統)在哪一次叉可能不會只是一個很好的守護進程?

+1

[創建守護進程時執行雙叉的原因是什麼?]的可能的重複?(http://stackoverflow.com/questions/881388/what-is-the-reason-for-performing-a- double -fork-when-creating-a-daemon) –

+0

我在我的問題中提到了這個問題,並且我已經閱讀了該問題的前3個答案。他們是很好的答案,但我仍然有一些不清楚,這已經包含在我的問題中 –

+0

鏈接問題中的一些答案也解釋了雙重分岔只在父級進程預期壽命比孩子長時才需要從而使孩子在父母的流程表中成爲殭屍)。 – Dunes

回答

1

作爲同一會話的一部分的進程意味着當你通過ssh斷開連接時bash接收到SIGHUP,它會終止會話中的所有進程。默認的SIGHUP處理程序也會終止進程。爲了避免這種情況,你想創建一個新的會話。另外,TTY是一個有些古老的概念,它經過多年的發展,已經獲得了巨大的歷史記錄和大量的用於交互性的角落案例,但是在運行守護進程時會適得其反,因爲您不希望內核發送隨機信號到TTY相關事件發生時,您的非交互式守護進程。


所以......你不想成爲TTY會議的成員,並且你不想成爲會議的領導者,因爲那些會得到信號。

這就是爲什麼你啓動一個守護進程:你運行python1,這個進程分叉,你得到python1和python2。 Python2開始新的會話和分支,所以你得到python3。

python2中的Setsid確保python3未連接到python1會話,並且需要在python2中分叉,因爲python2仍然是會話負責人。

然後,Python3將不會收到任何與TTY有關的信號,並且當您斷開連接或在箱子上發生任何與TTY有關的事情時,不會被SIGHUP殺死。