守護程序也稱為精靈程序(daemon),是執行在後台的一種特殊的程序。它獨立於控制終端並且週期性的執行某種任務負等待處理某些發生的事件。因為他們沒有控制終端,所以說他們是在後台執行的。
守護程序的特點:
(1)linux系統啟動時會啟動很多系統服務程序,守護程序沒有控制終端,不能直接和使用者互動。
(2)其他程序都是在使用者登入或者執行程式時建立,在執行結束或使用者登出時終止,但守護程序不受使用者登入登出的影響,只受開機關機的影響。
守護程序存在的原因:
daemon函式存在的原因是因為控制終端由於某些原因(如斷開終端連線)會傳送一些訊號的原因。而接受處理這些訊號的預設動作會讓程序退出。這些訊號會由於終端敲一些特殊按鍵產生。
守護程序和後台程序的區別:
(1)守護程序是後台程序,但後台程序不一定是守護程序
(2)守護程序執行是與終端無關的,是不能往終端上打訊息的。
(3)守護程序的會話和當前目錄,檔案描述符都是獨立的。後台執行只是終端進行了一次fork,讓程式在後台執行。
建立守護程序:
建立守護程序最關鍵的一步是呼叫setsid函式建立了乙個新的會話(session),並成為session leaser.
#include
pid_t setsid(void);
該函式呼叫成功時返回新建立的session的id(其實就是當前程序的id),出錯返回-1.注意,呼叫這個函式之前,當前程序不允許是程序組的leader,否則該函式返回-1.要保證當前程序不是不是程序組的leader也很容易,只要先fork再呼叫setsid就行了。fork建立的子程序和父程序在同乙個程序組裡面,程序組的leader必然是該組的第乙個程序,所以子程序不可能是改組的第乙個程序,在子程序中呼叫setsid就不會有問題了。
成功呼叫該函式的結果是:
(1)建立乙個新的session,當前程序稱為session leader,當前程序的id就是session的id。
(2)建立乙個新的程序組,當前程序稱為程序租的leader,當前程序的id就是程序租的id。
(3)如果當前程序原本有乙個控制終端,則他失去這個控制終端,稱為乙個沒有控制終端的程序。所謂失去程序終端是指,原來的程序終端仍然是可開啟的,仍然可以讀寫,但只是乙個普通的開啟檔案而不是控制終端了。
建立守護程序的步驟:
(1)呼叫umask將檔案模式建立遮蔽字設定為0
(2)父程序fork出子程序,然後子程序呼叫setsid,父程序直接退出(保證了子程序不是乙個程序組的程序組長)
(3)呼叫setsid建立乙個新的會話(呼叫成功會使呼叫程序成為會話的首程序,並成為乙個程序租的組長程序,呼叫程序沒有控制終端)
(4)將當前工作目錄更改為根目錄
(5)關閉不需要的檔案描述符
(6)忽略sigchld訊號。
要知道在建立守護程序的時候fork一次和fork兩次的兩者的區別,就要先知道第一次fork和第二次fork都起到什麼作用:
(1)呼叫一次fork的作用:
第一次fork的作用是讓shell認為這條命令已經終止,不用掛在終端輸入上,還有就是為了後面上的setsid服務,因為呼叫setsid函式的程序不能是組長程序,如果不fork出子程序,則此時的父程序是程序組長,就無法呼叫setsid。當子程序呼叫完setsid函式之後,子程序是會話組長也是程序組組長,並且脫離了控制終端,此時,不管控制終端如何操作,新的程序都不會收到一些訊號使得程序退出。
(2)第二次fork的作用:
雖然當前關閉了和終端的聯絡,但是後期可能會誤操作開啟了終端。
只有會話首程序能開啟終端裝置,也就是在fork一次,再把父程序退出,再次fork的子程序作為守護程序繼續執行,保證了該精靈程序不是對話期的首程序,第二次不是必須的,是可選的,市面上有些開源專案也是fork一次。
**:守護程序的特點:
(1)linux系統啟動時會啟動很多系統服務程序,守護程序沒有控制終端,不能直接和使用者互動。
(2)其他程序都是在使用者登入或者執行程式時建立,在執行結束或使用者登出時終止,但守護程序不受使用者登入登出的影響,只受開機關機的影響。
守護程序存在的原因:
daemon函式存在的原因是因為控制終端由於某些原因(如斷開終端連線)會傳送一些訊號的原因。而接受處理這些訊號的預設動作會讓程序退出。這些訊號會由於終端敲一些特殊按鍵產生。
守護程序和後台程序的區別:
(1)守護程序是後台程序,但後台程序不一定是守護程序
(2)守護程序執行是與終端無關的,是不能往終端上打訊息的。
(3)守護程序的會話和當前目錄,檔案描述符都是獨立的。後台執行只是終端進行了一次fork,讓程式在後台執行。
建立守護程序:
建立守護程序最關鍵的一步是呼叫setsid函式建立了乙個新的會話(session),並成為session leaser.
#include
pid_t setsid(void);
該函式呼叫成功時返回新建立的session的id(其實就是當前程序的id),出錯返回-1.注意,呼叫這個函式之前,當前程序不允許是程序組的leader,否則該函式返回-1.要保證當前程序不是不是程序組的leader也很容易,只要先fork再呼叫setsid就行了。fork建立的子程序和父程序在同乙個程序組裡面,程序組的leader必然是該組的第乙個程序,所以子程序不可能是改組的第乙個程序,在子程序中呼叫setsid就不會有問題了。
成功呼叫該函式的結果是:
(1)建立乙個新的session,當前程序稱為session leader,當前程序的id就是session的id。
(2)建立乙個新的程序組,當前程序稱為程序租的leader,當前程序的id就是程序租的id。
(3)如果當前程序原本有乙個控制終端,則他失去這個控制終端,稱為乙個沒有控制終端的程序。所謂失去程序終端是指,原來的程序終端仍然是可開啟的,仍然可以讀寫,但只是乙個普通的開啟檔案而不是控制終端了。
建立守護程序的步驟:
(1)呼叫umask將檔案模式建立遮蔽字設定為0
(2)父程序fork出子程序,然後子程序呼叫setsid,父程序直接退出(保證了子程序不是乙個程序組的程序組長)
(3)呼叫setsid建立乙個新的會話(呼叫成功會使呼叫程序成為會話的首程序,並成為乙個程序租的組長程序,呼叫程序沒有控制終端)
(4)將當前工作目錄更改為根目錄
(5)關閉不需要的檔案描述符
(6)忽略sigchld訊號。
要知道在建立守護程序的時候fork一次和fork兩次的兩者的區別,就要先知道第一次fork和第二次fork都起到什麼作用:
(1)呼叫一次fork的作用:
第一次fork的作用是讓shell認為這條命令已經終止,不用掛在終端輸入上,還有就是為了後面上的setsid服務,因為呼叫setsid函式的程序不能是組長程序,如果不fork出子程序,則此時的父程序是程序組長,就無法呼叫setsid。當子程序呼叫完setsid函式之後,子程序是會話組長也是程序組組長,並且脫離了控制終端,此時,不管控制終端如何操作,新的程序都不會收到一些訊號使得程序退出。
(2)第二次fork的作用:
雖然當前關閉了和終端的聯絡,但是後期可能會誤操作開啟了終端。
只有會話首程序能開啟終端裝置,也就是在fork一次,再把父程序退出,再次fork的子程序作為守護程序繼續執行,保證了該精靈程序不是對話期的首程序,第二次不是必須的,是可選的,市面上有些開源專案也是fork一次。
**:
daemon 程序為什麼要fork兩次
daemon 程序為什麼要fork兩次 daemon程序是後台守護程序,有時候也叫精靈程序 agent linux下server都是daemon程序。相信大部分開發人員都知道如何去寫乙個daemon程序。但是另一方面,大部分人不知道為什麼要這麼做,不少人是從某個地方copy乙個函式,拿來主義。但是具...
daemon 程序為什麼要fork兩次
daemon程序是後台守護程序,有時候也叫精靈程序 agent linux 下server都是daemon程序。相信大部分開發人員都知道如何去寫乙個daemon程序。但是另一方面,大部分人不知道為什麼要這麼做,不少人是從某個地方copy乙個函式,拿來主義。但是具體為什麼這麼實現,卻不是很透徹。見過一...
daemon 需要fork兩次原因
參考文章 第一次fork後子程序繼承了父程序的程序組id,但具有乙個新的程序id,這就保證了子程序不是乙個程序組的首程序 也就是說第一次fork的的子程序的sid pgid都是首程序繼續來的也就是主程序的 然後setsid是為了跟主程序的sid pgid脫離 都設定成子程序的sid pgid,雖然此...