C语言之进程控制(僵尸进程和守护进程)

进程控制编程

 

1、子进程先父进程先结束:如果子进程结束的时候,父进程不做任何处理,那么这个子进程的一些信息会被保留,比如子进程的文件描述符,此时的子进程会被称为僵尸进程。这种僵尸进程会给程序带来不可想象的伤害,所以我们要尽量避免僵尸进程的产生。

僵尸进程产生的过程:

(1)父进程调用fork创建子进程后,子进程运行直至其终止,它立即从内存中移除,但进程描述符仍然保留在内存中(进程描述符占有极少的内存空间)。

(2)子进程的状态变成EXIT_ZOMBIE,并且向父进程发送SIGCHLD 信号,父进程此时应该调用 wait() 系统调用来获取子进程的退出状态以及其它的信息。在 wait 调用之后,僵尸进程就完全从内存中移除。

(3)因此一个僵尸存在于其终止到父进程调用 wait 等函数这个时间的间隙,一般很快就消失,但如果编程不合理,父进程从不调用 wait 等系统调用来收集僵尸进程,那么这些进程会一直存在内存中。

(4)僵尸进程的处理一般是用wait()函数来处理。

代码:
#include 
#include 
#include 
#include 

int main()
{	
	pid_t pid = fork();             //fork产生子进程,返回值pid如果是-1代表错误,0则代表子进程,非0代表的是父进程。
                              //fork很特殊,它会复制父进程,然后在父进程中返回的是子进程的ID号,而在子进程中是返回的0;
	
	switch(pid)
	{
		case -1:
			perror("fork");
			exit(0);
		case 0:
			printf("我是子进程\n");
			break;              //子进程先父进程结束,产生僵尸进程
		default:
			printf("我是父进程\n");
			while(1);            //死循环防止父进程结束。
			break;
	}

	return 0;
}

2、父进程先子进程先结束:则该父进程的所有子进程的父进程都改变为init进程。我们称这些进程由init进程领养。其执行顺序大致如下:在一个进程终止时,内核逐个检查所有活动进程,以判断它是否是正要终止的进程的子进程,如果是,则该进程的父进程ID就更改为1(init进程的ID);

有init领养的进程不会称为僵死进程,因为只要init的子进程终止,init就会调用一个wait函数取得其终止状态。这样也就防止了在系统中有很多僵死进程。

如果父进程结束,那么子进程会被init进程领养,那么这个时候我们就不能直接对这个子进程进行操作了,这个时候这个子进程会在后台继续运行,这个时候我们称这个子进程为守护进程(或者精灵进程)。在计算机中,有很多的后台程序在运行,所以这个守护进程对我们来说是很重要的。

守护进程的代码:
#include 
#include 
#include 
#include 
#include 
#include 

int Daemonize()
{
	pid_t pid = fork();   //创建子进程
	if(pid == -1)
	{
		perror("fork");
		return -1;
	}
	else if(pid > 0)
	{
		exit(0);     //关闭父进程
	}
	
	umask(0);      //设置文件的掩码。
/*注释:文件权限掩码是指屏蔽掉文件权限中的对应位。比如,有个文件权限掩码是050,它就屏蔽了文件组拥有者的可读与可执行权限。由于使用fork函数新建的子进程继承了父进程的文件权限掩码,这就给该子进程使用文件带来了诸多的麻烦。因此,把文件权限掩码设置为0,可以大大增强该守护进程的灵活性。*/
	
	if(setsid < 0)    //设置新的会话,目的是让这个子进程从父进程脱离出来,不受任何父进程控制。
	{
		perror("setsid");
		return -1;
	}
	
	if(chdir("/") == -1)     //设置当前的工作目录。
	{
		perror("chdir");
		return -1;
	}
	
	close(0);    //关闭标志输入,标志输出,标准错误,不让它在终端显示打印信息。
	close(1);
	close(2);
	
	open("dev/null",O_RDONLY);  //文件的重定向,让这个守护进程的信息打印在一个文件里
	open("dev/null",O_RDWR);
	open("dev/null",O_RDWR);
	
	return 0;
}

int main()
{	
	Daemonize();  //守护进程函数
	while(1);   //死循环

	return 0;
}



你可能感兴趣的:(C语言之进程控制(僵尸进程和守护进程))