用C語言在Linux系統下建立守護程式(Daemon)
轉載自:
https://blog.csdn.net/str999_cn/article/details/78686923
守護程式(daemon)是指在後臺執行的,沒有控制終端與之相連的程式。它獨立於控制終端,週期性地執行某種任務。Linux的大多數伺服器就是用守護程式的方式實現的。如web伺服器程式http等。守護程式在後臺執行,類似於Windows中的系統服務。
編寫守護程式程式的要點:
(1)讓程式在後臺執行。方法是呼叫fork()產生一個子程式,然後使父程式退出。
(2)呼叫setsid()建立一個新對話期。控制終端、登入會話和程式組通常是從父程式繼承下來的,守護程式要擺脫它們,不受它們的影響,方法是呼叫setsid()使程式成為一個會話組長。setsid()呼叫成功後,程式成為新的會話組長和程式組長,並與原來的登入會話、程式組和控制終端脫離。
(3)禁止程式重新開啟控制終端。經過以上步驟,程式已經成為一個無終端的會話組長,但是它可以重新申請開啟一個終端。為了避免這種情況發生,可以通過使程式不再是會話組長來實現。再一次通過fork()建立新的子程式,使呼叫fork的程式退出。
(4)關閉不再需要的檔案描述符。子程式從父程式繼承開啟的檔案描述符。如不關閉,將會浪費系統資源,造成程式所在的檔案系統無法卸下以及引起無法預料的錯誤。首先獲得最高檔案描述符值,然後用一個迴圈程式,關閉0到最高檔案描述符值的所有檔案描述符。
(5)將當前目錄更改為根目錄。
(6)子程式從父程式繼承的檔案建立遮蔽字可能會拒絕某些許可權。為防止這一點,使用unmask(0)將遮蔽字清零。
(7)處理SIGCHLD訊號。對於伺服器程式,在請求到來時往往生成子程式處理請求。如果父程式不等待子程式結束,子程式將成為殭屍程式(zombie),從而佔用系統資源。如果父程式等待子程式結束,將增加父程式的負擔,影響伺服器程式的併發效能。在Linux下可以簡單地將SIGCHLD訊號的操作設為SIG_IGN。這樣,子程式結束時不會產生殭屍程式。
守護程式的例項:
- #include <stdio.h>
- #include <sys/types.h>
- #include <unistd.h>
- #include <signal.h>
- #include <sys/param.h>
- #include <sys/stat.h>
- #include <time.h>
- #include <syslog.h>
-
- int init_daemon(void)
- {
- int pid;
- int i;
-
- //忽略終端I/O訊號,STOP訊號
- signal(SIGTTOU,SIG_IGN);
- signal(SIGTTIN,SIG_IGN);
- signal(SIGTSTP,SIG_IGN);
- signal(SIGHUP,SIG_IGN);
-
- pid = fork();
- if(pid > 0) {
- exit(0); //結束父程式,使得子程式成為後臺程式
- }
- else if(pid < 0) {
- return -1;
- }
-
- //建立一個新的程式組,在這個新的程式組中,子程式成為這個程式組的首程式,以使該程式脫離所有終端
- setsid();
-
- //再次新建一個子程式,退出父程式,保證該程式不是程式組長,同時讓該程式無法再開啟一個新的終端
- pid=fork();
- if( pid > 0) {
- exit(0);
- }
- else if( pid< 0) {
- return -1;
- }
-
- //關閉所有從父程式繼承的不再需要的檔案描述符
- for(i=0;i< NOFILE;close(i++));
-
- //改變工作目錄,使得程式不與任何檔案系統聯絡
- chdir("/");
-
- //將檔案當時建立遮蔽字設定為0
- umask(0);
-
- //忽略SIGCHLD訊號
- signal(SIGCHLD,SIG_IGN);
-
- return 0;
- }
-
- int main()
- {
- time_t now;
- init_daemon();
- syslog(LOG_USER|LOG_INFO,"TestDaemonProcess! \n");
- while(1) {
- sleep(8);
- time(&now);
- syslog(LOG_USER|LOG_INFO,"SystemTime: \t%s\t\t\n",ctime(&now));
- }
- }
編譯執行上述程式。然後用ps -ef 命令檢視程式狀態,該程式狀態如下:
從結果可以看出該程式具備守護程式的所有特徵。
檢視/var/log目錄下,先前並不存在的test.log檔案已經有了。
用vi開啟該日誌檔案,記錄如下:
最後需要關閉此守護程式。關閉的方法是通過ps -ef命令查詢到該程式的程式號,之後再用kill 命令將其殺死。
注意:使用syslog函式前需要配置。但需要注意的是,在Centos6.x系統中,系統日誌的配置檔案已經發生了變化。不再是原來的/etc/syslog.conf了,而是/etc/rsyslog.conf。開啟上述檔案,在檔案末尾加入下面一行:
user.* /var/log/test.log
然後重啟syslog服務。重啟的命令也修改為:/etc/init.d/rsyslog restart
實際上,Linux提供了完成上述同樣功能的庫函式:
- #include <unistd.h>
- int daemon(int nochdir,int noclose);
其中,nochdir引數用於指定是否改變工作目錄,如果給它傳遞0,則工作目錄將被設定為“/”(根目錄),否則繼續使用當前工作目錄。noclose引數為0時,標準輸入、標準輸出和標準錯誤輸出都被重定向到/dev/null檔案,否則依然使用原來的裝置。該函式成功時返回0,失敗返回-1,並設定errno。
相關文章
- opentracker改造為daemon守護程式
- Linux下的守護程式分析Linux
- 深入理解Linux作業系統下的守護程式(轉)Linux作業系統
- Linux下C++ daemonLinuxC++
- Linux 守護程式Linux
- Linux下C語言驗證多程式LinuxC語言
- 建立 SysV 風格的 linux daemon 程式Linux
- 物聯網教程Linux系統程式設計——特殊程式之守護程式Linux程式設計
- Linux守護程式及SystemdLinux
- c語言實用小程式C語言
- Linux基礎命令---httpd守護程式Linuxhttpd
- Linux守護程式的啟動方法Linux
- linux平臺下C語言按程式名查詢程式號pidLinuxC語言
- C語言 16 系統庫C語言
- C語言建立空白Windows視窗程式碼C語言Windows
- 聊聊C語言/C++—程式和程式語言C語言C++
- 守護程式
- Linux下C語言編譯的問題LinuxC語言編譯
- 【C語言】linux下多檔案編譯C語言Linux編譯
- Linux下跨語言呼叫C++實踐LinuxC++
- 如何系統學習C 語言(下)之 檔案篇
- Linux-C語言LinuxC語言
- Kali Linux 2020.1修改系統語言Linux
- 在 Ubuntu 上透過命令列改變 Linux 系統語言Ubuntu命令列Linux
- Node 程式守護
- 程式守護 supervisor
- 在Linux系統下如何建立定時任務?操作介紹!Linux
- 本文幫你在 Unix 下玩轉 C 語言
- Linux系統推薦學習的程式語言以及經驗Linux
- 如何系統學習C 語言(下)之 預處理命令篇
- C語言指標應用程式設計C語言指標程式設計
- 守護程式那些事
- Golang 程式守護 SupervisorGolang
- C語言學生管理系統原始碼C語言原始碼
- C語言實戰!!!:商城系統模擬C語言
- c語言 5.9.2下載C語言
- Linux 檢視設定系統語言(轉)Linux
- 在ubuntu系統下用Makefile方式程式設計主程式Ubuntu程式設計