一、守護進程定義
守護進程也稱精靈進程( Daemon),是運行在後臺的一種特殊進程。它獨立於控制終端並且週期性地執行某種任務或等待處理某些發生的事件。守護進程是一種很有用的進程。 Linux的大多數服務器就是用守護進程實現的。比如,Internet服務器inetd,Web服務器httpd 等。同時,守護進程完成許多系統任務。比如,作業規劃進程crond等。
二、守護進程的創建方法
1.調用umask將文件模式創建屏蔽字設置爲0
2.創建子進程,父進程退出
由於守護進程是脫離控制終端的,因此,完成這一步後就會在Shell終端裏造成一程序已經運行完畢的假象。之後的所有工作都在子進程中完成,而用戶在Shell終端裏則可以執行其他命令,從而在形式上做到了與控制終端的脫離。
在Linux中父進程先於子進程退出會造成子進程成爲孤兒進程,而每當系統發現一個孤兒進程時,就會自動由1號進程(init)收養它,這樣,原先的子進程就會變成init進程的子進程。
3.在子進程中創建新會話
這個步驟是創建守護進程中最重要的一步,雖然它的實現非常簡單,但它的意義卻非常重大。使用的是系統函數setsid。
該函數調用成功時返回新創建的Session的id(其實也就是當前進程的id),出錯返回-1。注意,調用這個函數之前,當前進程不允許是進程組的Leader,否則該函數返回-1。所以第一步先創建子進程,fork創建的子進程和父進程在同一個進程組中,進程組的Leader必然是該組的第一個進程,所以子進程不可能是該組的第一個進程,在子 程中調用setsid就不會有問題了。
成功調用該函數的結果是:
(1)創建一個新的Session,當前進程成爲Session Leader,當前進程的id就是Session的id。
(2)創建一個新的進程組,當前進程成爲進程組的Leader,當前進程的id就是進程組id。
(3)如果當前進程原本有一個控制終端,則它失去這個控制終端,成爲一個沒有控制終端的進 程。所謂失去控制終端是指,原來的控制終端仍然是打開的,仍然可以讀寫,但只是一個普 通的打開文件而不是控制終端了。
4. 將當前工作目錄更改爲根目錄。
5. 關閉不在需要的文件描述符。
6. 其他:忽略SIGCHLD信號。
三、守護進程代碼實現
四、fork一次和兩次的區別
在創建守護進程時,創建子進程可以fork一次,也可以fork兩次。
第一次fork完成後,就會在Shell終端裏造成一程序已經運行完畢的假象。之後的所有工作都在子進程中完成,而用戶在Shell終端裏則可以執行其他命令,從而在形式上做到了與控制終端的脫離。
第二次fork是爲了防止後期可能會誤操作打開了終端。由於只有會話首進程能打開終端設備,所以再次fork,fork創建的子進程和父進程在同一個進程組中,進程組的Leader必然是該組的第一個進程,所以子進程不可能是該組的第一個進程。在子進程中調用setsid就沒有問題了。