daemon 程序為什麼要fork兩次

2021-07-10 17:46:51 字數 2231 閱讀 1985

daemon 程序為什麼要fork兩次

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

見過一些面試官或被面試人,很多人解釋daemon程序存在的理由是因為僵死程序,或者輸入輸出。其實和這些東西一毛錢關係都沒有。

daemon函式存在的原因是因為控制終端由於某些原因(如斷開終端鏈結)會傳送一些訊號的原因,而接收程序處理這些訊號預設動作會讓程序退出,這些訊號會由於終端上敲一些特殊按鍵而產生。

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

int daemon(void)

umask(0)

;pid = fork();

if( pid !

= 0)

exit

(0); /

/first child exit//

thechild of first child

chdir (

"/")

;for

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

int stdfd0 = open (

"/dev/null"

, o_rdwr)

;int

stdfd1 

=dup2(stdfd0, stdout_fileno)

;int

stdfd2 

=dup2(stdfd0, stderr_fileno)

;if((stdfd0 != 0) || (stdfd1 != 1) || (stdfd2 != 2))

//start normal work

//.........

return 0;

}1 、

第1次fork

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

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

3 、經過前面2個步驟,基本想要做的都做了。第2次fork不是必須的,也看到很多開源服務沒有fork第2次。fork第2次主要目的是:防止程序再次開啟乙個控制終端。因為開啟乙個控制終端的前提條件是該程序必須是會話首程序,再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程序是後台守護程序,有時候也叫精靈程序 agent linux 下server都是daemon程序。相信大部分開發人員都知道如何去寫乙個daemon程序。但是另一方面,大部分人不知道為什麼要這麼做,不少人是從某個地方copy乙個函式,拿來主義。但是具體為什麼這麼實現,卻不是很透徹。見過一...

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

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

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

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