首页 > 编程知识 正文

守护进程作用,守护进程的概念

时间:2023-05-04 06:05:44 阅读:249856 作者:834

目录 守护进程的特点常见的守护进程守护进程的编程规则编程规则设计原理守护进程的编程代码总结参考资料

守护进程的特点

守护进程是脱离终端并在后台运行的进程。守护进程不具有控制终端,我们不会再终端上见到守护进程的输出。守护进程也不会被终端发出的信号打断。

常见的守护进程

init 系统守护进程,启动系统服务
inetd 侦听网络接口,以便取得来自网络各种网络服务进程的请求

守护进程的编程规则 调用umask将文件模式创建屏蔽字设置为0。调用fork,父进程退出。调用setsid创建一个新会话。将当前工作目录更改为根目录。关闭不再需要的文件描述符。打开/dev/null使其具有文件描述符 0,1,2。 编程规则设计原理

有很多博文对守护进程的编程规则进行了阐述,但是很多不是直接抄书就是没讲清楚。接下来让我详细的分析,让大家把守护进程的生成过程弄明白。

调用umask将文件模式创建屏蔽字设置为0

在fork过程子进程继承会父进程的文件权限掩码,由继承得到的文件模式创建的屏蔽字可能会拒绝设置某些权限。例如,若守护进程要创建一个组可读/写的文件,而继承的文件模式创建屏蔽字可能屏蔽了这两种权限,创建的组就无法实现读写功能。调用umask将文件模式创建屏蔽字设置为0就消除了这种烦恼。

调用fork,父进程退出。

1)如果该守护进程是作为一条简单的shell命令启动的,那么⽗父进程终止使得shell认为该命令已经执行完毕。
2)保证子进程不是一个进程组的组长进程。
第二条没看懂不碍事,让我们结合下面一条编程规则一起看。

调用setsid创建一个新会话

编程步骤二其实是基于编程步骤三,因为进程不是一个进程组的组长时,调用setsid函数时才成功。
调用成功后,函数就会新建一个会话,结果将发生下面3件事:
1)该进程变为新会话首进程。此时,该进程是新会话中唯一的进程。
2)该进程成为新进程组的组长进程。新进程组ID是调用该进程的进程ID。
3)该进程没有控制终端
重点来了:
编程步骤二其实是就是希望能够成功调用setsid函数
编程步骤三调用setsid函数其实是使该进程没有控制终端!(还记得守护进程的特点吗)

调用setsid创建一个新会话之后,还会再次调用一次fork函数。那么第二次调用fork函数的目的是什么呢?
第二次调用fork函数生成的进程我把它叫孙子进程。由于进程组有子进程,在生成孙子进程之后,孙子进程也不会成为进程组的组长进程,孙子进程就没有权力打开终端。说白了目的还是为了使守护进程没有控制终端!

将当前工作目录更改为根目录。

如果守护进程的当前工作目录在一个装配文件中,那么该文件系统就不能被拆卸。

关闭不再需要的文件描述符

守护进程有能从父进程继承文件描述符,如果不进行关团的话将会浪费录统资源。

打开/dev/null使其具有文件描述符 0,1,2

文件描述符 0,1,2在改变之前指的是读标准输入、写标准输出和标准出错。这些都是与终端相连的文件描述符。说白了就是切断守护进程与终端的可能性,可见在守护进程的编程过程中,在断绝与终端的关系做足了功夫。

守护进程的编程代码

结合以上编程原理理解这个代码,看起来顺畅多了。

void daemonize(const char *cmd){int i, fd0, fd1, fd2;pid_t pid;struct rlimit rl;struct sigaction sa;umask(0);if(getrlimit(RLIMIT_NOFILE, &rl) < 0)err_quit("%s: cannot get file limit",cmd);if((pid = fork()) < 0)err_quir("%s: cannot fork", cmd);else if(pid != 0)exit(0);setsid();sa.sa_handler = SIG_IGN;sigemptyset(&sa.sa_mask);sa.sa_flags = 0;if(sigaction(SIGHUP, &SA, NULL) < 0)err_quit("s: cannot ignore SIGHUP");if((pid = fork() < 0)err_quit("%s: cannot fork", cmd);else if(pid != 0)exit(0);if(chdir("/") <0)err_quit("%s: cnnot change directory to /");if(rl.rlim_max == RLIM_INFINITY)rl.rlim_max = 1024;for(i = 0; i < rl.rlim_max; i++)close(i);fd0 = open("/dev/null", ORDWR);fd1 = dup(0);fd2 = fup(0);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);}} 总结

守护进程是脱离终端并在后台运行的进程。守护进程的编程过程其实使一个切断与终端联系的过程。

参考资料

UNIX环境高级编程
创建守护进程为什么要fork两次

Java聊天室之实现获取Socket功能使用已有的ULB 容器云 UK8S

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。