daemon 程序為什麼要fork兩次

2021-07-11 11:49:21 字數 1923 閱讀 8756

daemon程序是後台守護程序,有時候也叫精靈程序(agent).linux 下server都是daemon程序。相信大部分開發人員都知道如何去寫乙個daemon程序。但是另一方面,大部分人不知道為什麼要這麼做,不少人是從某個地方copy乙個函式,拿來主義。但是具體為什麼這麼實現,卻不是很透徹。

見過一些面試官或被面試人。很多人解釋daemon程序存在的理由是因為僵死程序。或者輸入輸出。其實和這些東西一毛錢關係都沒有。daemon函式存在的原因是因為控制終端由於某些原因(如斷開終端鏈結)會傳送一些訊號的原因。而接收進城處理這些訊號預設動作會讓程序退出。這些訊號會由於終端上敲一些特殊按鍵而產生。

貼乙個daemon函式常見的實現:

int daemon(void)

umask(0)

;pid = fork();

if( pid !

= 0)

exit

(0);//

second children

chdir (

"/")

;for

(int i = 0; i < 3; i++)

int stdfd = open (

"/dev/null"

, o_rdwr)

;dup2(stdfd, stdout_fileno)

;dup2(stdfd, stderr_fileno)

;return 0;}

1 、第一次fork的作用是讓shell 認為本條命令 已經終止,不用掛在終端輸入上。還有乙個作用是為後面setsid服務。setsid的呼叫者不能是程序組組長(group leader). 此時父程序是程序組組長。

2 、setsid() 是本函式最重要的乙個呼叫。它完成了daemon函式想要做的大部分事情。呼叫完整個函式。子程序是會話組長(sid==pid),也是程序組組長(pgid == pid),並且脫離了原來控制終端。到了這一步,基本上不管控制終端如何怎麼樣。新的程序都不會收到那些訊號。

3  、經過前面2個步驟,基本想要做的都做了。第2次fork不是必須的。也看到很多開源服務沒有fork第二次。fork第二次主要目的是。防止程序再次開啟乙個控制終端。因為開啟乙個控制終端的前台條件是該程序必須是會話組長。再fork一次,子程序id != sid(sid是程序父程序的sid)。所以也無法開啟新的控制終端。

daemon目的就是防止終端產生的一些訊號讓程序退出。上面函式並沒有直接呼叫signal函式去處理它。而是間接通過fork和setsid函式使用更少**優雅處理。而被有些人誤以為是僵死程序的原因需要這樣處理。

當然,也有很多程式不是像上面函式那樣去實現。而是直接通過忽略訊號方式處理。這樣其實也不錯,因為這些訊號很少會有用到的價值。直接忽略基本上不存在誤殺的情況。反正達到最終目的就可以。條條大路通羅馬。

下面羅列一下控制終端會產生哪些訊號。程式中只要處理好這些訊號,同樣能達到上面函式實現的目的。

//後台程序讀取/寫入終端輸入產生下面兩個訊號,或者控制終端不存在情況讀取和寫入會產生

signal(sigttou, sig_ign);

signal(sigttin, sig_ign);

//按ctrl-c ,ctrl-\ ctrl-z會向前臺程序組傳送下面這些訊號

signal(sigint,  sig_ign );

signal(sigquit, sig_ign );

signal(sigtstp, sig_ign );

//終端斷開,會給會話組長或孤兒程序組所有成員傳送下面訊號

signal(sighup,  sig_ign );

還有有些訊號也可以由終端shell產生,需要關注

signal(sigcont, sig_ign );

signal(sigstop, sig_ign );

上面這些訊號,應該有些程式預設處理(sig_dfl)本身動作就是忽略(sig_ign),不是退出程序。不過按照上面寫也不會造成什麼問題。

daemon 程序為什麼要fork兩次

daemon 程序為什麼要fork兩次 daemon程序是後台守護程序,有時候也叫精靈程序 agent linux下server都是daemon程序。相信大部分開發人員都知道如何去寫乙個daemon程序。但是另一方面,大部分人不知道為什麼要這麼做,不少人是從某個地方copy乙個函式,拿來主義。但是具...

為什麼要學習程序程式替換?

1 守護程序 父程序先啟動,建立乙個子程序,讓子程序程式替換成為另外乙個程式,實現不同的乙個功能,父子程序會程序通訊,進而完成當子程序異常退出的時候,父程序會重新啟動子程序。守護程序能有效解決子程序異常退出的問題,但是不能解決子程序退出本質,真正需要解決還得程式設計師debug。程序程式替換介面 i...

Android守護程序 為什麼要fork()兩次

雖然,我本身很排斥這種做法,有點類似 流氓軟體 的行為,但是還是查詢了資料,大概想了乙個實現的方式,和大家一起分享。其實,這個問題可以簡單的看作 如何編寫乙個守護程序。使用c c 編寫乙個守護程序的.so程式,android端通過jni呼叫。該程序監聽當前的目標程式程序,如果目標程式被kill掉了,...