什麼是daemon進程?Unix/Linux中的daemon進程類似於Windows中的後臺服務進程,一直在後臺運行運行,例如http服務進程nginx,ssh服務進程sshd等。 爲什麼daemon進程需要特殊的編寫步驟?daemon進程和普通進程不一樣嗎?爲什麼要單獨提出如何編寫daemon進程呢? > make & 讓編譯命令make到後臺執行,這樣只是造成了make在後臺一直運行的假象,它依然沒有脫離和terminal之間的父子關係; 如何編寫daemon進程?對於可以用多種方法解決的問題,我們一般只需熟練掌握其中一種最適合自己的即可; 1. 首先給出經典名著APUE中的方法:#include "apue.h" #include <syslog.h> #include <fcntl.h> #include <sys/resource.h> void daemonize(const char *cmd){ int i, fd0, fd1, fd2; pid_t pid; struct rlimit rl; struct sigaction sa; /* * Clear file creation mask. */ umask(0);//註釋1 /* * Get maximum number of file descriptors. */ if (getrlimit(RLIMIT_NOFILE, &rl) < 0) err_quit("%s: can't get file limit", cmd); /* * Become a session leader to lose controlling TTY. */ if ((pid = fork()) < 0)//註釋2 err_quit("%s: can't fork", cmd); else if (pid != 0) /* parent */ exit(0); setsid();//註釋3 /* * Ensure future opens won't allocate controlling TTYs. */ sa.sa_handler = SIG_IGN; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; if (sigaction(SIGHUP, &sa, NULL) < 0) err_quit("%s: can't ignore SIGHUP", cmd); if ((pid = fork()) < 0)//註釋4 err_quit("%s: can't fork", cmd); else if (pid != 0) /* parent */ exit(0); /* * Change the current working directory to the root so * we won't prevent file systems from being unmounted. */ if (chdir("/") < 0)//註釋5 err_quit("%s: can't change directory to /", cmd); /* * Close all open file descriptors. */ if (rl.rlim_max == RLIM_INFINITY) rl.rlim_max = 1024; for (i = 0; i < rl.rlim_max; i++) close(i);//註釋6 /* * Attach file descriptors 0, 1, and 2 to /dev/null. */ fd0 = open("/dev/null", O_RDWR);//註釋7 fd1 = dup(0);//註釋7 fd2 = dup(0);//註釋7 /* * Initialize the log file. */ openlog(cmd, LOG_CONS, LOG_DAEMON); if (fd0 != 0 || fd1 != 1 || fd2 != 2) { syslog(LOG_ERR, "unexpected file descriptors %d %d %d",fd0, fd1, fd2); exit(1); } } 下面是針對上面例子的詳細解釋: * 註釋1:因爲我們從shell創建的daemon子進程,所以daemon子進程會繼承shell的umask,如果不清除的話,會導致daemon進程創建文件時屏蔽某些權限。 針對這個例子,首先要說明的是,不管在Unix還是Linux上按照這個例子寫的daemon肯定沒問題。 1) 第二個fork是必須的嗎?
2. 利用系統庫函數daemon()創建daemon進程Linux系統還專門提供了一個用來創建daemon進程的系統函數: int daemon(int nochdir, int noclose); 從api的文檔描述看該api也調用了fork(),估計內部實現和上面的代碼邏輯類似,從其參數作用也可以看出這一點, #include <unistd.h> #include <stdlib.h> int main(void) { if(daemon(0,0) == -1) exit(EXIT_FAILURE); while(1) { sleep(60); } return 0; } 3. 使用第三方工具supervisor簡單的說supervisor是一個python工具,可以通過編寫配置文件來對指定的進程進行管理,比如啓動進程,停止進程以及進程退出後自動重啓等; 參考資料http://www.cnblogs.com/mickole/p/3188321.html |
linux中創建deamon進程的三種方法
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.