创建守护进程
守護(hù)進(jìn)程(daemon)。 守護(hù)進(jìn)程是一個(gè)后臺(tái)進(jìn)程,它無需用戶輸入就能運(yùn)行,經(jīng)常是提供某種服務(wù)。 Linux做為服務(wù)器是,主要的進(jìn)程也都是為系統(tǒng)或者用戶提供后臺(tái)服務(wù)功能。 常見的守護(hù)進(jìn)程有Web服務(wù)器、郵件服務(wù)器以及數(shù)據(jù)庫服務(wù)器等等。 守護(hù)進(jìn)程不能夠控制終端,所以任何輸入或者輸出都需要做特殊處理。 守護(hù)進(jìn)程看上去似乎很神秘,但如果牢記幾條規(guī)則而且知道幾個(gè)關(guān)鍵函數(shù),工作就很簡(jiǎn)單了。 首先執(zhí)行fork后讓父進(jìn)程退出。 和多數(shù)程序一樣,一個(gè)守護(hù)進(jìn)程是從shell腳本或者命令行啟動(dòng)的。 但守護(hù)進(jìn)程和應(yīng)用程序不一樣,因?yàn)樗鼈儾皇墙换ナ降?–它們?cè)诤笈_(tái)因而沒有控制終端。 父進(jìn)程在fork子進(jìn)程退出后就消除了控制終端。 守護(hù)進(jìn)程既不需要從標(biāo)準(zhǔn)輸入設(shè)備讀信息,也不需要從標(biāo)準(zhǔn)輸出設(shè)備輸出信息。 下一步是在子進(jìn)程中使用setsid調(diào)用創(chuàng)建新會(huì)話,調(diào)用setsid完成以下幾項(xiàng)工作。 –如果調(diào)用進(jìn)程不是一個(gè)進(jìn)程組的領(lǐng)導(dǎo)進(jìn)程,它就創(chuàng)建一個(gè)新會(huì)話,讓調(diào)用進(jìn)程成為新會(huì)話的會(huì)話領(lǐng)導(dǎo)。 –它讓調(diào)用進(jìn)程成為新進(jìn)程組的進(jìn)程組領(lǐng)導(dǎo)。 –它把進(jìn)程組ID(PGID)和會(huì)話ID(SID)設(shè)置為調(diào)用進(jìn)程的進(jìn)程ID(PID)。 –它取消進(jìn)程和任何控制終端的關(guān)聯(lián)。 下一步是讓根目錄成為子進(jìn)程的當(dāng)前工作目錄。 因?yàn)槿魏芜M(jìn)程如果它的當(dāng)前目錄是在一個(gè)被安裝的文件系統(tǒng)上,那么就會(huì)妨礙這個(gè)文件系統(tǒng)被卸載。 接下來設(shè)置進(jìn)程的umask為0。 為了避免守護(hù)進(jìn)程集成的umask收到創(chuàng)建文件和目錄操作的干擾,這一步是必要的。 如果一個(gè)進(jìn)程集成了父進(jìn)程的umask 055,他屏蔽掉了group和other的讀和執(zhí)行權(quán)。如果守護(hù)進(jìn)程接著創(chuàng)建了一個(gè)文件,那么對(duì)group和other用戶操作這個(gè)文件會(huì)帶來麻煩。 守護(hù)進(jìn)程調(diào)用 umask 0避免了這種情況,當(dāng)創(chuàng)建文件的時(shí)候給予守護(hù)進(jìn)程更大的靈活性。 最后關(guān)閉子進(jìn)程繼承的任何不必要的文件描述符。 對(duì)于子進(jìn)程來說,沒有理由保持從父進(jìn)程繼承來的打開的文件描述符。 具體關(guān)閉哪些取決與具體的守護(hù)進(jìn)程需要和要求,很難精確的說明規(guī)則。 創(chuàng)建守護(hù)進(jìn)程步驟總結(jié) –父進(jìn)程中執(zhí)行fork后,執(zhí)行exit退出。 –在子進(jìn)程中調(diào)用setsid。 –讓根目錄“/”成為子進(jìn)程的工作目錄。 –把子進(jìn)程的umask變?yōu)?。 –關(guān)閉任何不需要的文件描述符。 setsid函數(shù) pid_t setsid() setsid函數(shù)創(chuàng)建一個(gè)新會(huì)話和一個(gè)新進(jìn)程組,然后守護(hù)進(jìn)程成為新會(huì)話的會(huì)話領(lǐng)導(dǎo),以及新進(jìn)程組的進(jìn)程組領(lǐng)導(dǎo)。 setsid調(diào)用還保證新會(huì)話沒有控制終端。 如果調(diào)用進(jìn)程已經(jīng)是一個(gè)進(jìn)程組的領(lǐng)導(dǎo)進(jìn)程,setsid調(diào)用失敗。 setsid調(diào)用成功返回新會(huì)話ID,失敗返回-1,并設(shè)置errno。 chdir函數(shù) int chdir(const char *pathname) chdir函數(shù)根據(jù)參數(shù)pathname設(shè)置當(dāng)前工作。 chdir調(diào)用成功返回0,失敗返回-1,并設(shè)置errno。 umask函數(shù) mode_t umask(mode_t mask); umask調(diào)用把守護(hù)進(jìn)程的umask設(shè)置為0,這樣取消了來自父進(jìn)程的umask,它們能夠潛在的干擾創(chuàng)建文件和目錄。 創(chuàng)建守護(hù)進(jìn)程代碼例子。 void setdaemon()
{pid_t pid, sid;pid = fork();if (pid < 0){printf("fork failed\n");exit(EXIT_FAILURE);}if(pid > 0){exit(EXIT_SUCCESS);//in the parent
}if((sid = setsid()) < 0){printf("setsid failed\n");exit(EXIT_FAILURE);}if((chdir("/")) < 0){printf("chdir failed\n");exit(EXIT_FAILURE);}umask(0);//close(STDIN_FILENO);//if close stdin,then daemon_console failed
close(STDOUT_FILENO);close(STDERR_FILENO);
}
?
?
一旦系統(tǒng)調(diào)用setsid,它就不再有控制終端,所以也就無處發(fā)送正常情況下應(yīng)該發(fā)往stdout或者stderr的輸出。 可以通過syslog提供服務(wù),記錄守護(hù)進(jìn)程的各種輸出信息。 openlog函數(shù)打開日志,syslog寫入日志,closelog關(guān)閉日志。 #include <syslog.h> void openlog(const char *ident, int option, int facility); void syslog(int priority, const char *format, ...); void closelog(void); openlog函數(shù)發(fā)起到系統(tǒng)日志服務(wù)器的連接,參數(shù)ident是要向每個(gè)消息加入的字符串,典型的情況是要設(shè)置成程序的名稱。 參數(shù)option是下面一個(gè)或多個(gè)值的“或”| 名稱 | 含義 |
| LOG_CONS | 如果系統(tǒng)日志服務(wù)器不能用,寫入控制臺(tái) |
| LOG_NDELAY | 立即打開連接,正常情況下,直到發(fā)送第一條消息才打開連接 |
| LOG_PERROR | 打印輸出到stderr |
| LOG_PID | 每條消息中包含進(jìn)程 PID |
?
?
參數(shù)facitity指定程序發(fā)送消息的類型。| 名稱 | 含義 |
| LOG_AUTHPRIV | 安全授權(quán)消息 |
| LOG_CRON | 時(shí)鐘守護(hù)進(jìn)程:cron和at |
| LOG_DAEMON | 其他系統(tǒng)守護(hù)進(jìn)程 |
| LOG_KERN | 內(nèi)核消息 |
| LOG_LPR | 打印機(jī)子系統(tǒng) |
| LOG_MAIL | 郵件子系統(tǒng) |
| LOG_USER | 默認(rèn) |
?
?
參數(shù)priority指定消息的重要性。| 名稱 | 含義 |
| LOG_EMERG | 系統(tǒng)不能使用 |
| LOG_ALERT | 立即采取措施 |
| LOG_CRIT | 緊急事件 |
| LOG_ERR | 出錯(cuò)條件 |
| LOG_WARNING | 警告條件 |
| LOG_NOTICE | 正常但重大事件 |
| LOG_INFO | 信息消息 |
| LOG_DEBUG | 調(diào)試信息 |
?
?
syslog代碼例子:yslog(LOG_INFO, "my daemin is OK");
嚴(yán)格的說,openlog和closelog是可選的,因?yàn)楹瘮?shù)syslog在首次使用的時(shí)候自動(dòng)打開日志文件。 linux系統(tǒng)上日志文件通常是/var/log/messages。 復(fù)制去Google翻譯翻譯結(jié)果轉(zhuǎn)載于:https://www.cnblogs.com/shichuan/p/4496188.html
總結(jié)