守護進程也稱精靈進程,是運行在後台的一種特殊進程。他獨立於終端並且周期性執行某種任務或者等待某件事情的發生。守護進程是一種很有用的進程。比如很多的服務器都是以次方是運行在後台,等待客戶端連接並處理相關問題的。
系統中守護進程通常以d結尾標識。
創建守護進程關鍵的一步是調用setsid函數創建一個新的會話,並使之稱為控制進程。
注:調用setsid創建守護進程的當前進程不得是進程組的leader,否則返回-1;保證這個條件的方式是:我們在當前進程進行fork生成子進程,父進程直接退出,子進程調用setsid就可以了。
1。創建一個新的會話,並且當前進程稱為leader,當前進程id為會話id
2。創建一個新的進程組,當前進程是進程組的leader,當前進程id就是進程組id
3。如果當前進程原本有一個控制終端,那麼他失去這個終端稱為一個沒有終端控制的進程。
1調用umask將文件屏蔽字設置為0
2調用fork,父進程退出
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; }
這個則是系統中提供的設置守護進程的函數。
由圖我們可以看到,守護進程是脫離終端的。
http://xxxxxx/Linuxjc/1144281.html TechArticle