前言
在之前的學習中我們瞭解到了殭屍進程的相關知識(殭屍進程博客:https://blog.csdn.net/Outtch_/article/details/105160491),其實在Linux系統中還有兩種特殊的進程——孤兒進程和守護進程(精靈進程)。
孤兒進程和守護進程又是什麼呢?它們有什麼特殊的地方呢?它們怎麼出現的呢?它們怎麼用代碼實現呢?
相信大家對這兩種陌生的進程也有着許許多多的疑惑,接下來讓我們一起去認識它們吧!
孤兒進程的概念
在法律層面上,孤兒是指喪失父母的未成年人。
同樣的在Linux系統中的孤兒進程的概念是父進程先於子進程退出,子進程就成爲了孤兒進程運行在後臺
。
值得一提的是孤兒進程雖然沒有了父進程,但是它會被1號init進程收養,成爲init進程的子進程,子進程退出後,會由init進程對它們完成狀態收集工作,所以孤兒進程並沒有什麼危害。
守護進程(精靈進程)的概念
普通進程都是依附於終端會話(系統與用戶交流的界面)運行,當控制終端關閉時,相應的進程也被關閉。
守護進程(Deamon)其實是一種特殊的孤兒進程,守護進程脫離終端會話的影響運行在後臺,它從被執行開始運轉直到整個系統關閉時才退出
,守護進程通常是批處理進程(週期性的執行某項任務),守護進程又叫做精靈進程。
- 守護進程的應用場景:
應用於不想讓進程受到用戶或終端影響的場景下
大多數的服務器都是守護進程實現的(ssh:xshell的遠程連接)
守護進程的實現
- 第一步:創建子進程,退出父進程
使子進程成爲孤兒進程
,之後所有的工作都在子進程中完成,在形式上做到了與控制終端的脫離。
- 第二步:使用系統函數setsid在子進程中創建新的會話
由於子進程複製了父進程的會話、進程組、控制終端。
雖然父進程退出了,但會話、進程組、控制終端始終沒有變
,因此子進程還不是真正意義上的獨立。
setsid
可以讓進程擺脫原會話、進程組、控制終端的控制,使進程完全獨立出來。
- 第三步:改變工作目錄
子進程繼承了父進程的工作目錄
由於在進程的運行過程中,當前目錄所在的文件系統不能卸載,對以後工作會造成不便。
一般會將根目錄設置爲守護進程的工作目錄
(chdir函數)
- 第四步:重設文件權限掩碼
文件創建掩碼是指屏蔽掉文件創建時的對應位
子進程繼承了父進程的文件權限掩碼,這就給子進程使用文件帶來了諸多麻煩。
把文件權限掩碼設置爲0,可以大大增強守護進程的靈活性umask(0)
。
- 第五步:關閉文件描述符
子進程繼承了父進程已經打開的文件,這些文件可能不會被守護進程讀寫,但它們一樣在消耗系統資源。
守護進程已經與終端失去了聯繫
所以文件描述符爲0、1、2
的3個文件已經失去了意義(輸入 、輸出、報錯)因該關掉。
- 第六步:處理SIGCHLD信號
signal ( SIGCHLD , SIG_IGN ) 使父進程等待子進程退出
這樣內核在子進程結束時不會產生殭屍進程
具體代碼實現:
ps -ajx | grep Deamon命令查看守護進程
可見進程ID 進程組ID 會話ID都相同
進程ID爲3466的進程是一個守護進程
守護進程實則就是一個普通進程按照上述步驟改造而來的
小結
到這裏我們對孤兒進程和守護進程的概念以及實現已經有了一個大致的認識,在日後的學習中如果我們碰到類似的問題便能很好的解決它們。