C說話編寫Linux守護過程實例。本站提示廣大學習愛好者:(C說話編寫Linux守護過程實例)文章只能為提供參考,不一定能成為您想要的結果。以下是C說話編寫Linux守護過程實例正文
守護過程(Daemon)是運轉在後台的一種特別過程。它自力於掌握終端而且周期性地履行某種義務或期待處置某些產生的事宜。守護過程是一種很有效的進 程。Linux的年夜多半辦事器就是用守護過程完成的。好比,Internet辦事器inetd,Web辦事器httpd等。同時,守護過程完成很多體系任 務。好比,功課計劃過程crond,打印過程lpd等。
守護過程的編程自己其實不龐雜,龐雜的是各類版本的Unix的完成機制不盡雷同,形成分歧Unix情況下守護過程的編程規矩其實不分歧。這須要讀者留意,照搬 某些書上的規矩(特殊是BSD4.3和低版本的System V)到Linux會湧現毛病的。上面將周全引見Linux下守護過程的編程要點並給出具體實例。
一. 守護過程及其特征
守護過程最主要的特征是後台運轉。在這一點上DOS下的常駐內存法式TSR與之類似。其次,守護過程必需與其運轉前的情況隔分開來。這些情況包含未封閉的 文件描寫符,掌握終端,會話和過程組,任務目次和文件創立掩模等。這些情況平日是守護過程從履行它的父過程(特殊是shell)中繼續上去的。最初,守 護過程的啟動方法有其特別的地方。它可以在Linux體系啟動時從啟動劇本/etc/rc.d中啟動,可以由功課計劃過程crond啟動,還可以由用戶終端 (平日是shell)履行。
總之,除開這些特別性之外,守護過程與通俗過程根本上沒有甚麼差別。是以,編寫守護過程現實上是把一個通俗過程依照上述的守護過程的特征改革成為守護過程。假如讀者對過程有比擬深刻的熟悉就更輕易懂得和編程了。
二. 守護過程的編程要點
後面講過,分歧Unix情況下守護過程的編程規矩其實不分歧。所幸的是守護過程的編程准繩其實都一樣,差別在於詳細的完成細節分歧。這個准繩就是要知足守護 過程的特征。同時,Linux是基於Syetem V的SVR4並遵守Posix尺度,完成起來與BSD4比擬更便利。編程要點以下;
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下必需顯式期待子過程停止能力釋放僵屍過程。
三. 守護過程實例
守護過程實例包含兩部門:主法式test.c和初始化法式init.c。主法式每隔一分鐘向/tmp目次中的日記test.log申報運轉狀況。初始化法式中的init_daemon函數擔任生成守護過程。讀者可以應用init_daemon函數生成本身的守護過程。
1. init.c清單
#include < unistd.h >
#include < signal.h >
#include < sys/param.h >
#include < sys/types.h >
#include < sys/stat.h >
void init_daemon(void)
{
int pid;
int i;
if(pid=fork())
exit(0);//是父過程,停止父過程
else if(pid< 0)
exit(1);//fork掉敗,加入
//是第一子過程,後台持續履行
setsid();//第一子過程成為新的會話組長和過程組長
//並與掌握終端分別
if(pid=fork())
exit(0);//是第一子過程,停止第一子過程
else if(pid< 0)
exit(1);//fork掉敗,加入
//是第二子過程,持續
//第二子過程不再是會話組長
for(i=0;i< NOFILE;++i)//封閉翻開的文件描寫符
close(i);
chdir(“/tmp”);//轉變任務目次到/tmp
umask(0);//重設文件創立掩模
return;
}
2. test.c清單
#include < stdio.h >
#include < time.h >
void init_daemon(void);//守護過程初始化函數
main()
{
FILE *fp;
time_t t;
init_daemon();//初始化為Daemon
while(1)//每隔一分鐘向test.log申報運轉狀況
{
sleep(60);//睡眠一分鐘
if((fp=fopen(“test.log”,”a”)) >=0)
{
t=time(0);
fprintf(fp,”I'm here at %sn”,asctime(localtime(&t)) );
fclose(fp);
}
}
}
以上法式在RedHat Linux6.0下編譯經由過程。步調以下:
編譯:gcc –g –o test init.c test.c
履行:./test
檢查過程:ps –ef
從輸入可以發明test守護過程的各類特征知足下面的請求。