守護進程


一、守護進程的概念:

守護進程就是通常說的daemon進程,是linux后台執行的一種進程,他的特點就是,生存周期長,獨立於控制終端並且周期性的執行某種任務,不會隨着終端的關閉而停止運行,直到接收到停止信息才會結束運行。

二、守護進程的創建:

  1. 創建子進程,父進程退出。
if (fork()) {

    exit(0);    

}

先解釋這個語句的意思:

/*

* fork()函數:

* 三種返回值:

* 0:子進程中返回0

* > 0:在父進程中返回子進程ID

* -1  : 出錯返回-1

* 所以通過判斷是不是0,就能判斷是不是子進程,不是子進程的全部退出。

* */

為什么做這一步?

         由於守護進程是脫離終端而存在的,所以先給終端一種假死的狀態,之后的工作都在子進程中進行。

           父進程退出后,子進程沒有父進程變成了一個孤兒進程,Linux中,每當系統發現一個孤兒進程,就會自動由1號進程(也就是init進程:內核啟動的一號進程)收養它,這樣子進程就變成了init進程的子進程。

  2.在子進程中創建新會話:

setsid()

  這個步驟是創建守護進程最重要的一步,雖然實現非常簡單,但意義卻非常重大。在這里使用的是系統函數setsid(),在具體介紹setsid()之前,讀者首先要了解兩個概念:進程組和會話期。

  進程組。進程組是一個或多個進程的集合。進程組由進程組ID來唯一標識。除了進程號(PID)之外,進程組ID也是一個進程的必備屬性。

  每個進程組都有一個組長進程,其組長進程的進程號等於進程組ID,且該進程ID不會因組長進程的退出而受到影響。

  會話期。會話組是一個或多個進程組的集合。通常,一個會話開始於用戶登錄,終止於用戶退出,在此期間該用戶運行的所有進程都屬於這個會話期。

  接下來就可以具體介紹setsid()的相關內容。

  setsid()函數的作用。setsid()函數用於創建一個新的會話組,並擔任該會話組的組長。調用setsid()有以下3個作用:

    讓進程擺脫原會話的控制。

    讓進程擺脫原進程組的控制。

    讓進程擺脫原控制終端的控制。

  那么,在創建守護進程時為什么要調用setsid()函數呢?讀者可以回憶一下創建守護進程的第一步, 在那里調用了fork()函數來創建子進程再令父進程退出。由於在調用fork()函數時,子進程全盤復制了父進程的會話期、進程組和控制終端等,雖然父進程退出了,但原先的會話期、進程組和控制終端等並沒有改變,因此,還不是真正意義上的獨立。而setsid()函數能夠使進程完全獨立出來,從而脫離所 有其他進程的控制。

  3.改變當前目錄為根目錄。

  這一步也是必要的步驟。使用fork()創建的子進程繼承了父進程的當前工作目錄。由於在進程運行過程中,當 前目錄所在的文件系統(如“/mnt/usb”等)是不能卸載的,這對以后的使用會造成諸多的麻煩(如系統由於某種原因要進入單用戶模式)。因此,通常的 做法是讓“/”作為守護進程的當前工作目錄,這樣就可以避免上述問題。當然,如有特殊需要,也可以把當前工作目錄換成其他的路徑,如/tmp。改變工作目 錄的常見函數是chdir()。

  4.重設文件權限掩碼。

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

  5.關閉文件描述符。

  同文件權限掩碼一樣,用fork()函數新建的子進程會從父進程那里繼承一些已經打開的文件。這些被打開的文件可能永遠不會被守護進程讀或寫,但它們一樣消耗系統資源,而且可能導致所在的文件系統無法被卸載。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM