歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Linux編程---守護進程

Linux編程---守護進程

日期:2017/3/1 10:03:54   编辑:Linux編程

Linux守護進程

linux服務器在啟動時需要啟動很多系統服務,他們向本地和網絡用戶提供了linux的系統功能接口,直接面向應用程序和用戶。提供這些服務的程序是由運行在後台的守護進程來執行的。

守護進程是運行在後台,生存期長的一種特殊服務進程,他們獨立於控制終端並且周期性的執行某種任務或等待處理某些發生的事件。他們常常在系統引導裝入時啟動,在系統關閉時終止。

由於在linux中,每一個系統終端與用戶進行交流的界面稱為終端,每一個從終端開始運行的進程都依附於這個終端,這個終端就稱為這些進程的控制終端,當控制終端被關閉時,相應的進程都會自動關閉。但是守護進程卻能夠突破這種限制,它從被執行開始運轉,直到整個系統關閉時才退出。如果想某個進程不因為用戶,終端或其他進程的變化而受到影響,那麼就必須把這個進程變成一個守護進程。

編寫規則:

1:創建子進程,父進程退出

這是創建守護進程的第一步,由於守護進程是脫離控制終端的,因此,完成第一步後就會在shell終端造成一個程序已經運行完畢的現象。之後的所有工作都在子進程完成。

在linux中父進程先於子進程退出稱為孤兒進程,而每當系統發現一個孤兒進程時,就會自動由1號進程(init)收養它,這樣,原先的子進程就會變成init進程的子進程。

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

在這裡使用的是系統函數setsid,在具體介紹setsid之前,首先了解兩個很重要的概念。

(1):進程組。它是一個或多個進程的集合。進程組由進程組ID來唯一標識。除了進程號(PID)之外,進程組ID也是一個進程的必備屬性。每個進程組都有一個組長進程,其組長進程的進程號等於進程組ID。且該進程組ID不會因組長的退出而受到影響。

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

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

1:讓進程擺脫原會話的控制

2:讓進程擺脫原進程組的控制

3:讓進程擺脫原控制終端的控制

那麼,在創建守護進程時,為什麼要調用setsid函數呢?呵呵~這個問題其實想想就會明白了

由於在我們創建守護進程的第一步調用了fork()函數來創建子進程,在將父進程退出。由於調用fork()函數時,子進程全盤復制了父進程的會話期,控制終端等,但會話期,進程組,控制終端等並沒有改變,因此,這不是真正意義上的獨立開來,而setsid函數能夠使進程完全獨立出來,從而擺脫其他進程的控制。

3:改變當前目錄為根目錄

使用fork創建的子進程繼承了父進程的當前工作目錄。由於在進程運行中,當前目錄所在的文件系統(如:/mnt/usb)是不能卸載的。這對以後的使用會造成很多的麻煩,所以我們在使用u盤的時候盡量不要強制拔出,這樣對u盤會有相當的損壞。因此通常的做法是讓“/”作為守護進進程的當前工作目錄,這樣就可以避免上述的問題,當然,如果有什麼特殊需要的話,也可以把當前目錄切換到其他的路徑。如/tmp。改變工作目錄的常見函數是chdir

4:重置文件的權限掩碼

首先要做的是調用umask將文件模式創建屏蔽字設為0。因為由繼承得來的文件模式創建屏蔽字可能會拒絕設置某些權限

5:關閉文件描述符

同文件權限碼一樣,用fork函數新建的子進程會從父進程那裡繼承一些已經打開了的文件。這些被打開的文件可能永遠不會被守護進程讀寫,但他們一樣消耗了系統資源,而且可能導致所在的文件系統無法掛載。所以那些文件描述符失去存在的價值,應該關閉。

Copyright © Linux教程網 All Rights Reserved