[Linux]守护进程(精灵进程)

来源:互联网 发布:网络语人肉什么意思 编辑:程序博客网 时间:2024/05/22 08:50

一、守护进程是什么

守护进程是生存期很长的一种进程,可以说它是7*24小时工作的。(什么是7*24,一周7天,每天24小时,这不就是一年365天一直在工作嘛,还搞的这么诙谐,哈哈)。它们常常在系统引导装入时启动,仅在系统关闭时才终止。因为它们没有控制终端,所以说它们是在后台运行的,而且它没法直接和用户交互。当然在后台运行的可不一定是守护进程哦。Unix下有很多守护进程,执行日常事务。守护进程是一种很有用的进程,Linux下的很多服务器大多是用守护进程实现的。比如Internet服务器inetd,Web服务器httpd等。

守护进程还有一个特点:其它进程都是在用户登录或运行程序时创建,在运行结束或用户注销时终止,但系统服务进程不受用户登录注销的影响,它们一直在运行着。

我们用ps -axj来查看系统中的进程。-a显示由其他用户所拥有的进程的状态,-x显示没有控制终端的进程,-j显示与作业有关的信息(进程组ID,会话ID,控制终端,终端进程组ID)。守护进程通常以d为结尾。

这里写图片描述

由上述的进程中,TPGID为-1的都是没有控制终端的进程,也是守护进程。还有像COMMAND那一列中,用[]括起来的进程名,都表示内核线程。这些线程在内核里创建,没有用户空间代码,因此没有程序文件名和命令行,以k开头,表示Kernel。它自成进程组,自成会话。

进程1通常是init,它是一个系统守护进程。

二、创建守护进程

我们写一个mydaemon:

步骤哈:1.创建守护进程首先得,调用umask来将文件模式创建屏蔽字设置为0。

2.调用fork,使父进程退出。因为在这里,后面使用setid不允许进程为进程组id,因此得先将父进程exit。

3.调用setid创建一个新会话,成为会话首进程,成为进程组组长,没有控制终端。这就是守护进程的特点吧。

4.将当前的工作目录改为根目录。你想想,如果你将守护进程的工作目录设置为当前工作目录而非根目录,那么如果将这个目录删除后,就会导致严重的丢失问题。你的那个目录将不能被删除。

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

守护进程实现:

#include<stdio.h>#include<stdlib.h>#include<unistd.h>#include<signal.h>void mydaemon(){    umask(0);    if(fork() <=  0)//child    {}    else//father    {        exit(0);    }    setsid();    signal(SIGCHLD,SIG_IGN);    close(0);    close(1);    close(2);    chdir("/");}int main(){    mydaemon();//  daemon(0,0);    while(1);    return 0;}

运行结果:

这里写图片描述

这样一个守护进程就写好啦。当然库里边也实现了一个守护进程,daemon函数。

int daemon(int nochdir, int noclose);

这里nochdir表示不改变当前守护进程的目录,noclose表示不关闭进程文件描述符。

当前我们是把工作目录修改了,所以:

这里写图片描述

当我们都设置为0时,daemon(0,0);说明修改; 当我们都设置为1时,daemon(1,1);说明不修改;

三、为什么创建守护进程时有人fork两次?

第二次fork的作用:虽然当前关闭了和终端的联系,但是后期可能会误操作打开了终端。只有会话首进程能打开终端设备,也就是再fork一次,再把父进程退出,再次fork的子进程作为守护进程继续运行,保证了该精灵进程不是会话的首进程,第二次不是必须的,是可选的,市面上有些开源项目也是fork一次。(再次fork一次,保证daemon进程,之后不会打开tty设备)