【Linux系統編程】守護進程

    守護進程又稱精靈進程,常常在系統啓動時自啓,僅在系統關閉時才終止,生存期比較長!一般都是在後臺運行,不需要和用戶交互。

    可通過ps -axj命令查看常用系統守護進程,其中最爲常見的init進程,負責各運行層次間的系統服務。

    在說守護進程編程流程之前先來了解幾個概念:

    會話:一個或多個進程組的集合。用戶從登錄到退出期間的所有進程都屬於一個會話期。會話id = 會話首進程的pid

    進程組:一個或多個進程的集合。進程組的id=父進程的id,即父進程就是進程組長。

    創建守護進程的必要性:打開終端,運行的第一個程序爲bash。若關閉終端,整個會話就會結束。爲了防止會話意外結束或其他,可以創建一個新的會話。

    創建新會話的條件:只能是普通的組員進程纔可創建新會話。不能是會話首進程或進程組長。

    守護進程編程流程:

    1.調用fork()創建子進程,然後退出父進程

    上邊已經提到,創建新會話必須是普通的組員進程,而父進程一般是進程組長,因此要先執行fork()並退出父進程。

    2.調用setsid()在子進程中創建一個新會話

    使進程獨立出來,脫離控制。

    3.執行fork()退出父進程,使其失去進程組長身份

    fork的目的是確保守護進程來即使打開一個終端設備,也不會自動控制終端。

    4.將當前目錄更改爲根目錄,chdir("/")

    進程活動時,其工作目錄所在的文件系統不能卸下。一般需要將工作目錄改變到根目錄。使用fork創建的子進程繼承了父進程的當前工作目錄。由於在進程運行中,當前目錄所在的文件系統(如“/mnt/usb”)是不能卸載的,這對以後的使用會造成諸多的麻煩(比如系統由於某種原因要進入單用戶模式)。因此,通常的做法是讓”/”作爲守護進程的當前工作目錄,這樣就可以避免上述的問題。

    5.調用umask()函數,設置進程的文件權限掩碼爲0

    文件權限掩碼是指屏蔽掉文件權限中的對應位。比如,有個文件權限掩碼是050,它就屏蔽了文件組擁有者的可讀與可執行權限。由於使用fork函數新建的子進程繼承了父進程的文件權限掩碼,這就給該子進程使用文件帶來了諸多的麻煩。因此,把文件權限掩碼設置爲0,可以大大增強該守護進程的靈活性。通常的使用方法爲umask(0)。

    6.關閉不再需要的文件描述符

    同文件權限碼一樣,用fork函數新建的子進程會從父進程那裏繼承一些已經打開了的文件。這些被打開的文件可能永遠不會被守護進程讀寫,但它們一樣消耗系統資源,而且可能導致所在的文件系統無法卸下。 
    在上面的第二步之後,守護進程已經與所屬的控制終端失去了聯繫。因此從終端輸入的字符不可能達到守護進程,守護進程中用常規方法(如printf)輸出的字符也不可能在終端上顯示出來。所以,文件描述符爲0、1和2 的3個文件(常說的輸入、輸出和報錯)已經失去了存在的價值,也應被關閉。

    7.守護進程退出處理 
    當用戶需要外部停止守護進程運行時,往往會使用 kill 命令停止該守護進程。所以,守護進程中需要編碼來實現 kill 發出的signal信號處理,達到進程的正常退出。

    

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章