守护进程的概念和实例。

1.守护进程?

  什么使守护进程呢?守护进程大体上来讲就是一个脱离了终端控制的进程,它的生存周期是从系统启动以后被系统加载启动的进程,直到系统关闭,从而就完成了一个守护进程的生命周期。它的特点是,在执行过程中,不会有任何信息出现在控制终端,与此同时也不会受到任何控制终端的终端信息干扰。如果想生成一个进程不被任何终端打断,那么守护进程是首选选择。

2.守护进程的实现过程?

  a.通过fork函数创建一个子进程,之后父进程退出,这样子进程自己仍旧在运行,这样就能达到子进程脱离了终端的控制.(此时的子进程就成了孤儿进程,实质上会被init进程所收养)。

 b.创建新的会话在子进程中,因为父进程创建了子进程,自己虽然退出了,但是子进程继承了父进程的所有资源,原先父进程的一些文件权限和某些操作还都是存在,在子进程中可能不需要这些操作。所以子进程需要创建一个新的会话,linux中提供setid()函数来为子进程设置一个新的会话组,这是守护进程的核心过程。并且该会话是该会话组的组长。

进程组:是一个或者多个进程的集合。每个进程组都有一个进程组id来唯一标识,其中组长的进程id就是该会话组的id值。并且进程组不会因为组长的进程id和进程组id一样,在组长进程退出的时候,不会影响进程组中的其他进程。

会话期:是一个或多个进程的集合,它的周期是从会话开始到该会话结束为一个会话期。例如从登陆一个终端到退出这个终端的 过程。

 c.setid()函数的介绍

 #include <sys/types.h>

 #include <unistd.h>

 pid_t setsid( void );

 调用setsid()将创建一个会话期和新的进程组,调用进程为该会话期和进程组组长,并且该进程没有控制终端。

 setsid()调用将返回新创建的进程组ID,并且该进程组ID等同于调用进程的进程ID。失败则返回-1,并设置errno的值指出错误原  因。

如果进程已经是会话组长时,setsid()调用将失败,但我们已经保证进程不是会话组长(第一次fork())。setsid()调用成功后,进程称为新的会话期组长,并与原来的登陆会话和进程组脱离。由于会话进程对控制端具有独占性,进程将同时与控制终端脱离。

d.修改守护进程的工作目录,因为子进程生成的时候都是继承的父进程的当前工作目录,这样是为了让子进程彻底的摆脱父子进程的影响.

e.修改文件掩码属性,同样是因为继承的问题,同样为了摆脱所有的父进程的相关属性,需要重新设置该进程的文件掩码属性。

f.关闭相关的文件描述符,为了节约资源,关闭不必要的文件描述符,通过继承得来的。

g.最后是关闭守护进程可以自定义信号处理函数来通过外部来关闭自守护进程的运行。

具体实现如下:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/wait.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>


void signal_handle(int sign){

    pid_t pid = getpid();
    exit(0);
}
int main(int argc,char** argv ){


    pid_t pid;

    int i ;
    char * buff = "This is dameon\n";
    int len = strlen(buff);
    
    pid = fork();

   if(pid > 0){
        exit(0); //father process exit

    }else if(pid ==0){
    
        setsid(); //使子进程独立1.摆脱原会话控制 2.摆脱原进程组的控制 3.摆脱控制中端的控制
        chdir("/"); //改变当前工作目录
        umask(0);
        for(i= 0;i< 65535;++i){ //关闭所有的终端
            close(i);
        }

        signal(SIGKILL,signal_handle);
        while(1){
    
            
            int fd = open("/tmp/dameon.txt",O_CREAT|O_WRONLY|O_APPEND,0600);
            if(fd < 0){
                printf("open file failed\n");
                exit(0);
            }

            write(fd,buff,len + 1);
            close(fd);
            sleep(3);

        }
    }
    return 0;
}





猜你喜欢

转载自blog.csdn.net/qq_26105397/article/details/80290314