您的位置:首页 > 其它

僵尸进程,孤儿进程

2018-03-17 12:48 281 查看
         前几天我们学了进程,进程又分为很多的状态。
        一般来说,进程有三个状态,即就绪状态,运行状态,阻塞状态。

        运行态:进程占用CPU,并在CPU上运行;
        就绪态:进程已经具备运行条件,但是CPU还没有分配过来;

        阻塞态:进程因等待某件事发生而暂时不能运行;
        在一些系统中,又增加了一些新状态,如挂起状态,可运行状态,深度睡眠状态,浅度睡眠状态,暂停状态,僵死状态。

        可运行状态:运行状态和就绪状态的合并,表示进程正在运行或准备运行,Linux 中使用TASK_RUNNING 宏表示可运行状态。        浅度睡眠状态:进程正在睡眠(被阻塞),等待资源的到来是唤醒,也可以通过其他进程信号或时钟中断唤醒,进入运行队列。Linux 中使用TASK_UNINTERRUPTIBLE  宏表示此状态。        深度睡眠状态:其和浅度睡眠基本类似,但不可被其他进程信号或时钟中断唤醒。        暂停状态:进程暂停执行接受某种处理。Linux 使用TASK_STOPPED 宏表示此状态。        僵死状态:进程已经结束但未释放进程控制块(PCB),Linux 使用TASK_ZOMBIE 宏表示此状态。        挂起状态:在执行状态的进程通过挂起即可进入就绪状态,由活动态向静止态转换就是通过挂起实现的。        
        今天我们就来具体说说僵尸进程和孤儿进程。
        僵尸进程:一个进程使用fork创建子进程,如果子进程退出,而父进程并没有调用wait或waitpid获取子进程的状态信息,那么子进程的进程描述符仍然保存在系统中。这种进程称之为僵死进程。如果进程不调用wait / waitpid的话, 那么保留的那段信息就不会释放,其进程号就会一直被占用,但是系统所能使用的进程号是有限的,如果大量的产生僵死进程,将因为没有可用的进程号而导致系统不能产生新的进程. 此即为僵尸进程的危害,应当避免。
        下面我们来演示一下僵尸进程的代码        


        
        这里说一下,本来这个代码我是想实现子进程退出,然后父进程僵死五秒后退出,但是测试过程中出了点问题,我就改成利用循环让父进程永不退出来实现僵尸进程,但是“I am father process,I will sleep five seconds\n"没有改动,这句话的地方大家可以随意改动,后面会看到这个代码的运行结果就明白了。        这个代码是用fork函数建立两个进程,如果id等于0的时候,他就是子进程,当id等于1的时候他就是父进程。我们如下是运行结果。
        


        我们可以看到 “I am father process,I will sleep five seconds"这几句话一直运行,没有停止,(如果你想要停止,就按crtl+c)子进程的pid 是49003 ,ppid是49002,下面我们就来看看进程是否变成僵尸进程。
        


        我打开另一个终端,输入命令 ps aux | egrep 49003,我们可以看到显示为 Z+ 已经变成的僵尸进程。由此,我们就实现了僵尸进程。
        
        孤儿进程:一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程。孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作。孤儿进程是没有父进程的进程,孤儿进程这个重任就落到了init进程身上,init进程就好像是一个民政局,专门负责处理孤儿进程的善后工作。每当出现一个孤儿进程的时候,内核就把孤儿进程的父进程设置为init,而init进程会循环地wait()它的已经退出的子进程。这样,当一个孤儿进程凄凉地结束了其生命周期的时候,init进程就会代表党和政府出面处理它的一切善后工作。因此孤儿进程并不会有什么危害。
        下面我们来演示一下孤儿进程的代码
        


                孤儿进程这个代码我们可以用僵尸进程的代码修改而成,孤儿进程我们让父进程退出,子进程存活。因为父进程退出,子进程就会被一号进程领养。如下为运行结果。        


        如图我们可以看到这个进程的ppid为1,说明已被一号进程领养。
        
    
        
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: