守護程序也稱Daemon(精靈)程序,是Linux中的後臺服務程序,通常獨立於控制終端並且週期性地執行某種任務或等待處理某些發生的事件。一般採用以d結尾的名字。如httpd,nfsd、sshd等
Linux後臺的一些系統服務程序,沒有控制終端,不能直接和使用者互動。不受使用者登入、登出的影響,一直在執行著,它們都是守護程序。如:預讀入緩輸出機制的實現;ftp伺服器;nfs伺服器等
建立守護程序,最關鍵的一步是呼叫setsid函式建立出來一個新的session,併成為session leader
建立守護程序模型:
1、建立子程序,父程序退出
所有工作在子程序中進行形式上脫離了控制終端
2、在子程序中建立會話
setsid()函式
使子程序完全獨立出來,脫離控制
3、改變當前目錄位置
chdir()函式
防止佔用可解除安裝的檔案系統
也可以換成其他路徑
4、重設檔案許可權掩碼
umask()函式
防止繼承的檔案建立遮蔽字拒絕某些許可權
增加守護程序靈活性
5、關閉/重定向檔案描述符
繼承的開啟檔案不會用到,浪費系統資源,無法解除安裝
6、開始執行守護程序核心工作守護程序退出處理程式模型,while()
守護程序demo:
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <time.h> void daemonize() { pid_t pid; // 建立子程序,並結束父程序 pid = fork(); if (pid < 0) { perror("fork"); exit(EXIT_FAILURE); } if (pid > 0) { exit(EXIT_SUCCESS); } // 建立新會話 if (setsid() < 0) { perror("setsid"); exit(EXIT_FAILURE); } // 修改當前工作目錄 if (chdir("/") < 0) { perror("chdir"); exit(EXIT_FAILURE); } // 設定umask umask(0); // 關閉標準輸入、輸出、錯誤流,並重定向到/dev/null close(STDIN_FILENO); close(STDOUT_FILENO); close(STDERR_FILENO); open("/dev/null", O_RDWR); // stdin dup2(0, STDOUT_FILENO); // stdout dup2(0, STDERR_FILENO); // stderr } void main_loop() { FILE *log_file; time_t current_time; // 開啟日誌檔案 log_file = fopen("/tmp/daemon.log", "a+"); if (log_file == NULL) { perror("fopen"); exit(EXIT_FAILURE); } // 每隔一段時間向日志檔案中寫入訊息 while (1) { time(¤t_time); fprintf(log_file, "Daemon is running... %s", ctime(¤t_time)); fflush(log_file); sleep(10); // 10秒 } fclose(log_file); } int main() { // 建立守護程序 daemonize(); // 進入主迴圈 main_loop(); return 0; }
執行結果:
daemon守護程序會在後臺執行,可以在/tmp/daemon.log中獲取到相應的log資訊: