守护进程

        一个进程主要关系有:  会话组、进程组、父子进程关系等。
        通常,在同一控制台下执行、运行的程序属于同一会话组;父子进程属于同一进程组;一个会话组可包含多个进程组。

        守护进程(精灵进程),顾名思义,就像护花使者一个样在背后默默支持着他的花儿;也像父亲一直保卫着,守护着孩子们的成长,

        当一个进程成为孤儿进程之后,再改变此孤儿进程的会话组、进程组,然后再赋予它特殊使命(在后台孜孜不倦的完成莫特定功能),就可以说此进程为守护进程。

 

        一个普通进程成为守护进程的过程:
        1.让普通进程的父进程先于它退出,此普通进程将被1号进程收养,成为孤儿进程;
        2.用setpgid或setsid改变此孤儿进程关系;
           当一个进程成为孤儿进程后,可以用 setpgid() 可以设置进程组ID为自己,但会话组不会变;
           当一个进程成为孤儿进程后,用setsid设置会话组为自己,同时进程组也会变为自己;他的子进程也会跟随变动。
        3.此时的进程程摆脱了原会话的控制;摆脱了原进程组的控制;摆脱了原控制终端的控制;
           此时的进程即为守护进程,在后台运行,可以让它周期性的执行特殊任务。

 

        下面这个程序是一个守护进程监控一个子进程,一旦这个子进程退出,守护进程会将它拉起。

 

//主程序

#include <unistd.h>
#include <iostream.h>
#include <signal.h>
#include <sys/wait.h>

void daemon()
{
    pid_t pid;	
    pid = fork();
    if (pid < 0)
    {
        cout<<"fork failed."<<endl;
        return;
    }	
	
    else if (pid == 0)
    {    //由于在调用了fork函数时,子进程全盘拷贝了父进程的会话期、进程组、控制终端等,虽然父进程退出了,但会话期、进程组、控制终端等并没有改变,因此,这还不是真正意义上的独立开来,而setsid函数能够使进程完全独立出来,从而摆脱其他进程的控制。		
    //在子进程中调用setsid()后,子进程成为新会话首进程,且成为一个组长进程,其进程组id等于会话id		
        setsid();
        return;
    }
	 
    else 
    {	 
      //让其父进程立即终止,使得子进程能在init下运行;这种方法通常被称为“脱壳”。
      exit(0);  
    } 

}

//拉起子进程
void run_sonprocess()
{
    pid_t child_pid=fork();
    if(child_pid<0)
    {
	cout<<"fork failed."<<endl;
	return;
    }
    else if(child_pid==0)
    {
		cout<<"begin run son process"<<endl;
		char path[50]="./son";
		execlp(path,"son",(char*)0);
    }
    else
    {
	cout<<"I'm daemon"<<endl;
    }
}

void re_run(int)
{
    int status;
    pid_t child_pid;
    child_pid=wait(&status);
    if(child_pid<0)
      return;
    else
    {
	cout<<"Warning: process "<<child_pid<<" is exit"<<endl;
    }
    //重新执行	
    run_sonprocess();
}

int main()
{
    signal(SIGCHLD, re_run);
    daemon();  
    run_sonprocess();
    for(;;)
	;
    return(0);
				
}


//子程序

#include <iostream.h>
int main()
{
    for(int loop=0; loop<10; loop++)
    {
	cout<<"son process is running " <<loop<<endl;
        sleep(2); 
    }
    return 1;
}


 

你可能感兴趣的:(守护进程)