守护进程也称精灵进程,是运行在后台的一种特殊进程。他独立于终端而且周期性执行某种任务或者等待某件事情的发生。守护进程是一种颇有用的进程。好比不少的服务器都是以次方是运行在后台,等待客户端链接并处理相关问题的。服务器
系统中守护进程一般以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; }
这个则是系统中提供的设置守护进程的函数。
由图咱们能够看到,守护进程是脱离终端的。