UNIX環境高階程式設計讀書筆記(十三) 守護程序

2021-04-30 08:22:10 字數 3017 閱讀 9486

守護程序也稱精靈程序是生存期長的一種程序,它們常常在系統引導裝入時啟動,在系統管比時終止。精靈程序沒有控制終端,所以它們是在後台執行的。守護程序是一種很有用的程序。

linux

的大多數伺服器就是用守護程序實現的。比如,

internet

伺服器inetd

,web

伺服器httpd

等。同時,守護程序完成許多系統任務。比如,作業規劃程序

crond

,列印程序

lpd等。

所有精靈程序都以超級使用者(使用者id為

0)的優先權執行。沒有乙個精靈程序具有控制終端—控制名稱設定為問號、終端前台程序組

id設定為

-1。除

update

以外的所有精靈程序都是組的首程序,對話期的首程序,而且是這些程序組和對話期中的唯一程序。所以的精靈程序的父程序都是

init

程序。守護程序最重要的特性是後台執行。在這一點上

dos下的常駐記憶體程式

tsr與之相似。其次,守護程序必須與其執行前的環境隔離開來。這些環境包括未關閉的檔案描述符,控制終端,會話和程序組,工作目錄以及檔案建立掩模等。這些環境通常是守護程序從執行它的父程序(特別是

shell

)中繼承下來的。最後,守護程序的啟動方式有其特殊之處。它可以在

linux

系統啟動時從啟動指令碼

/etc/rc.d

中啟動,可以由作業規劃程序

crond

啟動,還可以由使用者終端(通常是

shell

)執行。

建立精靈程序的步驟是:

1.呼叫

fork

,然後使父程序

exit. 2.

呼叫setsid

以建立乙個新對話期。

3.將當前工作目錄更改為根目錄。

4.將檔案方式建立遮蔽字設定為0。

5.關閉不需要的檔案描述符。

6.某些守護程序開啟

/dev/null

使其具有檔案描述符0,

1,2這樣任何乙個試圖讀標準輸入寫標準輸出或標準出錯的庫歷程都不會產生任何效果。

詳細步驟:

1. 在後台執行。

為避免掛起控制終端將

daemon

放入後台執行。方法是在程序中呼叫

fork

使父程序終止,讓

daemon

在子程序中後台執行。

if(pid=fork())

exit(0);//

是父程序,結束父程序,子程序繼續

2. 脫離控制終端,登入會話和程序組

有必要先介紹一下

linux

中的程序與控制終端,登入會話和程序組之間的關係:程序屬於乙個程序組,程序組號(

gid)就是程序組長的程序號(

pid)。登入會話可以包含多個程序組。這些程序組共享乙個控制終端。這個控制終端通常是建立程序的登入終端。

控制終端,登入會話和程序組通常是從父程序繼承下來的。我們的目的就是要擺脫它們,使之不受它們的影響。方法是在第

1點的基礎上,呼叫

setsid()

使程序成為會話組長:

setsid();

說明:當程序是會話組長時

setsid()

呼叫失敗。但第一點已經保證程序不是會話組長。

setsid()

呼叫成功後,程序成為新的會話組長和新的程序組長,並與原來的登入會話和程序組脫離。由於會話過程對控制終端的獨占性,程序同時與控制終端脫離。

3. 禁止程序重新開啟控制終端

現在,程序已經成為無終端的會話組長。但它可以重新申請開啟乙個控制終端。可以通過使程序不再成為會話組長來禁止程序重新開啟控制終端:

if(pid=fork())

exit(0);//

結束第一子程序,第二子程序繼續(第二子程序不再是會話組長)

4. 關閉開啟的檔案描述符

程序從建立它的父程序那裡繼承了開啟的檔案描述符。如不關閉,將會浪費系統資源,造成程序所在的檔案系統無法卸下以及引起無法預料的錯誤。按如下方法關閉它們:

for(i=0;i

關閉開啟的檔案描述符

close(i);>

5. 改變當前工作目錄

程序活動時,其工作目錄所在的檔案系統不能卸下。一般需要將工作目錄改變到根目錄。對於需要轉儲核心,寫執行日誌的程序將工作目錄改變到特定目錄如

/tmpchdir("/")

6. 重設檔案建立掩模

程序從建立它的父程序那裡繼承了檔案建立掩模。它可能修改守護程序所建立的檔案的訪問位。為防止這一點,將檔案建立掩模清除:

umask(0);

7. 處理sigchld

訊號處理

sigchld

訊號並不是必須的。但對於某些程序,特別是伺服器程序往往在請求到來時生成子程序處理請求。如果父程序不等待子程序結束,子程序將成為殭屍程序(

zombie

)從而占用系統資源。如果父程序等待子程序結束,將增加父程序的負擔,影響伺服器程序的併發效能。在

linux

下可以簡單地將

sigchld

訊號的操作設為

sig_ign

。signal(sigchld,sig_ign);

這樣,核心在子程序結束時不會產生殭屍程序。這一點與

bsd4

不同,bsd4

下必須顯式等待子程序結束才能釋放殭屍程序。

建立乙個守護程序的例子。

#include

#include

#include

int daemon_init(void)

int main()

我們執行後可以用

ps命令檢查該精靈程序的狀態。

#ps –axj

ppidpid

pgid

sidtttpgid

uidcommand

1735735735?-1224./jingling

二.為了正常運作,某些守護程序實現為單例項的,也就是在任一時刻只執行該守護程序的乙個副本。

unix 環境高階程式設計 讀書筆記

unix環境高階程式設計 讀書筆記 第8章exit和 exit區別 exit會直接進入核心,不會關閉io流。程序基本控制函式還有 wait,fork,exec。atexit 程式正常退出時呼叫,如果因為signal退出則不能呼叫。功能 註冊函式可以完成一些清理工作,比如全域性log類,可以不設定析構...

unix環境高階程式設計 讀書筆記

檔案 unix支援在不同程序之間共享開啟的檔案。核心使用三種資料結構表示開啟的檔案 原子操作 一般而言,原子操作指的是由多步組成的操作。如果該操作原子的執行,要麼執行完所有步,要麼一步也不執行,不可能只執行所有步驟的乙個子集。2 注意 原子操作函式 pread,pwrite pread 相當於呼叫r...

Unix環境高階程式設計 讀書筆記一

unix 基礎知識 這一章主要是unix系統的概論以及一些概念的介紹,主要分為10個小節 1 登陸 2 檔案和目錄 3 輸入和輸出 4 程式和程序 5 ansi c 6 出錯處理 7 使用者標識 8 訊號 9 unix時間值 10 系統呼叫和庫函式 這個都比較簡單,就不再重複敘述了。在標頭檔案中定義...