守護進程也稱精靈進程,是運行在後臺的一種特殊進程。他獨立於終端而且週期性執行某種任務或者等待某件事情的發生。守護進程是一種頗有用的進程。好比不少的服務器都是以次方是運行在後臺,等待客戶端鏈接並處理相關問題的。服務器
系統中守護進程一般以d結尾標識。函數
建立守護進程關鍵的一步是調用setsid函數建立一個新的會話,並使之稱爲控制進程。spa
注:調用setsid建立守護進程的當前進程不得是進程組的leader,不然返回-1;保證這個條件的方式是:咱們在當前進程進行fork生成子進程,父進程直接退出,子進程調用setsid就能夠了。code
1。建立一個新的會話,而且當前進程稱爲leader,當前進程id爲會話idblog
2。建立一個新的進程組,當前進程是進程組的leader,當前進程id就是進程組id進程
3。若是當前進程本來有一個控制終端,那麼他失去這個終端稱爲一個沒有終端控制的進程。it
1調用umask將文件屏蔽字設置爲0io
2調用fork,父進程退出class
3調用setsid建立會話:結果1調用進程成爲會話首進程,2調用進程成爲進程組組長,3調用進程沒有控制終端後臺
4將當前目錄更改成根目錄
5關閉沒必要要的文件描述符
6忽略SIGCHID信號
#include <signal.h> #include <stdlib.h> #include <fcntl.h> #include <sys/stat.h> #include <stdio.h> #include <unistd.h> void my_daemon() { int i; int fd0; pid_t pid; struct sigaction sa; umask(0); //設置文文件掩碼爲0 if( (pid = fork()) < 0 ) { }else if (pid != 0) { exit(0); //終止止父父進程 } setsid(); //設置新會話 sa.sa_handler = SIG_IGN; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; if( sigaction(SIGCHLD, &sa, NULL ) < 0 ) { // 註冊子子進程退出忽略信號 return; } if( (pid = fork())<0) { //再次fork,終止止父父進程,保持子子進程不是話首首進程,從而而保證後續 不會在和其餘終端關聯 printf("fork error!\n"); return; }else if( pid != 0) { exit(0); } if( chdir("/") < 0 ) {//更改工工做目目錄到根 printf("child dir error\n"); return; } close(0); fd0 = open("/dev/null", O_RDWR); // 關閉標準輸入入,重定向全部標準(輸入入輸出錯誤) 到/dev/null dup2(fd0, 1); dup2(fd0, 2); } int main(int argc, char const *argv[]) { my_daemon(); while(1) sleep(1); return 0; }
注:以上代碼,是根據定義方式,本身實現的守護進程設置過程。
#include <stdio.h> #include <unistd.h> int main(int argc, char const *argv[]) { daemon(0,0); while(1); return 0; }
這個則是系統中提供的設置守護進程的函數。
由圖咱們能夠看到,守護進程是脫離終端的。