2014-10-16 117 views
2

我正在嘗試編寫一個基本的多處理tcp-server,它爲每個新accept()分配一個進程。Linux:分叉兩次和守護進程之間的區別(ise)

我不需要父進程來等待子進程。我遇到了兩個解決方案 - 分叉兩次並守護進程。

  1. 這兩者有什麼區別?
  2. 哪種更適合這種情況?
  3. 選擇其中之一時需要注意哪些因素?
+2

你讀過[守護進程(3)](http://man7.org/linux/man-pages/man3/daemon.3.html)嗎?你知道[setsid(2)](http://man7.org/linux/man-pages/man2/setsid.2.html)嗎? – 2014-10-16 13:17:16

+3

我不會考慮一個好的設計。在主進程中保留子PID的列表並且定期收穫它們(當然是非阻塞的)有什麼問題?守護進程對於將主服務進程從其開始的終端分離開來很有用,因此它可以在後臺「永久」運行。 – 5gon12eder 2014-10-16 13:24:42

+0

我閱讀手冊頁。關於使用方面,我沒有明確的說法。 – Zaxter 2014-10-17 11:16:20

回答

1

需要的父進程(最終)wait()每個子進程,否則孩子會流連直到父退出。這是資源泄漏的一種形式。

分叉兩次,中間過程在分叉後立即退出,允許原始過程立即(通過wait())收集孩子,並使孫子過程成爲孤兒,系統負責清理。這是避免積累殭屍進程的一種方法。孫子與原來的過程保持在同一個過程組(因此也是同一個過程)。

守護進程有一個不同的目的。它將生成的(子進程)進程置於沒有控制終端的新會話(和新進程組)中。通過分叉一次可以實現同樣的效果,父母立即呼叫_exit(),孩子呼叫setsid()

系統服務將守護程序以轉義其啓動的會話,以免會話結束時關閉。這與多處理無關,但與流程管理有很大關係。一個過程爲了避免(大)子過程的過程管理職責而雙重分叉;這既有多處理又有過程管理方面。

同樣需要注意的是,雙重分流不僅僅是過程管理的責任,它也會放棄流程管理的能力。這是否是一個好的取捨取決於情況。

+0

謝謝你有見地的答案。 – Zaxter 2014-10-17 11:24:36

2

有一個微妙的區別。

分叉兩次:中級子進程不能成爲殭屍,只要它已經退出並且已被父級等待。孫子不能成爲殭屍,因爲它的父母(中等程度的孩子過程)已經退出,所以孫子是孤兒。孤兒(孫子)由init繼承,如果現在退出,系統負責清理它。通過這種方式,父母的流程就有了等待收集孩子退出狀態信號的責任,父母也可以忙於做其他工作。這也使得孩子能夠長時間運行,以便短時間的父母不需要等待那段時間。

守護進程:這是一個程序,希望從控制終端中脫離出來並作爲系統守護進程在後臺運行。沒有控制終端。

方法的決定取決於手頭的需求/場景。