建立守護程序的深入分析

2021-07-30 09:18:28 字數 1919 閱讀 9494

原文:

建立守護程序的過程有兩種:

一、fork兩次

int main()

二、

int main()

其實兩種方法在某種程度上來說都可以,但是double fork會帶來一些區別。

首先,我們得搞清楚這些**都幹了什麼:

1、第一次fork,確保當前的process一定不是session leader,關於session,繼續往下看

2、setsid,建立新的session,因為session leader呼叫setsid不會建立新session,所以我們才需要之前的那個fork。

那session到底是什麼?當你通過控制台登入時,你就建立了乙個session,乙個session就是乙個controlling terminal、乙個controlling process group,再加上一堆後台process group,其中controlling process一般就是login shell,controlling terminal就是你在敲鍵盤看顯示器的那個「終端」。在shell中,你可以用」&」將乙個命令在後台執行,或者你可以按ctrl-z,然後用bg命令將其放入後台,這時你可以用jobs命令看到後台執行的程序,這些後台程序就是background process group

看看當你logout的時候會發生什麼,此時controlling terminal會被關閉,這個session中所有程序都會收到sighup和sigterm/sigquit,對於這些訊號的預設操作就是結束程序。

作為乙個daemon,你當然不希望使用者logout的時候就退出,解決方案有幾種,一種就是忽略上述所有訊號,例如nohup程式幹的就是這個,但這樣做有個小問題,很多程式使用訊號作為一種簡單的ipc機制,忽略這些訊號會導致這種ipc失效;另外一種方案就是讓程序從這個controlling terminal上脫離,setsid將會建立乙個新的session,使當前程序成為新session的leader,並且不再關聯之前session的controlling terminal。

3、第二次fork,這件事情有點晦澀,其實很多文件上並沒說的太清楚,具體原因是這樣的,即使乙個程序建立了新的session,它依然有可能獲得乙個controlling terminal,比如你可以用ioctl(tiocsctty),這樣做的後果就是,新的session有了controlling terminal,然後前面我們提到的所有問題依然可能發生。為了徹底解決這個問題,我們需要第二次fork,因為ioctl(tiocsctty)手冊中在非常不起眼的地方提到了,只有session leader才能為session開啟controlling terminal,第二次fork之後,子程序就是session中第二個程序,它這輩子再沒機會成為session leader了(除非它呼叫setsid),也就再沒能力開啟controlling terminal了。這樣我們就一勞永逸的解決了所有問題。

所以,如果你的程式行為很固定,你知道它不會無聊到去開啟controlling terminal的話,第二次fork其實是不必要的,但是如果你是在寫乙個庫,而且不知道使用它的程式到底會有什麼樣的行為,你最好還是再fork一次。

其實幹了所有上述的事,依然還有一些遺留問題,你還需要:

1、chdir(「/」),這樣可以防止你的程式工作目錄所在的檔案系統無法umount的問題

2、close/reopen所有你不需要的fd,尤其是stdin/stdout,因為這些fd是從父程序繼承下來的,如果它們是管道,而對端有關閉了,讀寫它們會產生sigpipe

3、設定正確的umask,這也是從父程序繼承下來的,不一定是你想要的值

4、設定適當的env,同上

5、設定適當的sigmask

6、如果你的daemon需要建立子程序,你可能還需要signal(sigchld, sig_ign),防止退出的子程序成為zombie

IsPostBack深入分析

1 ispostback 介紹 ispostback是 page類有乙個 bool型別的屬性,用來判斷針對當前 form的請求是第一次還是非第一次請求。當 ispostback true時表示非第一次請求,我們稱為 postback,當 ispostback false時表示第一次請求。在 asp....

深入分析ConcurrentHashMap

再多執行緒的情況下,如果使用hashmap,就會導致死迴圈,導致cpu利用率接近100 所以如果是併發的情況不要使用hashmap 導致死迴圈主要是這段 當在多執行緒的情況由於沒有同步導致,著段 在擴容的時候會執行 do while e null 執行緒安全的hashtable 容器 hashtab...

深入分析malloc

本文大量參考了如何實現乙個malloc這篇文章。任何乙個用過或學過c的人對malloc都不會陌生。大家都知道malloc可以分配一段連續的記憶體空間,並且在不再使用時可以通過free釋放掉。但是,許多程式設計師對malloc背後的事情並不熟悉,許多人甚至把malloc當做作業系統所提供的系統呼叫或c...