《深入理解计算机系统》第八章 (三)回收子进程

原创 2013年12月03日 11:33:05

进程总是处在下面三种状态的一种:

(1)运行(2)停止(3)终止。 

进程终止的原因:

(1)收到一个默认行为是终止进程的信号    (2)从主程序中返回    (3)调用exit函数

一个终止了但是没有被回收的进程成为僵死进程。进程一般是通过父进程进行回收,如果父进程没有回收它的僵死的子进程就终止了,那么内核就安排init进程来回收它们。init进程的PID为1,并且实在系统初始化的时候由内核创建的。僵死进程虽然没有运行,但是依然消耗系统的存储器资源,父进程回收已终止的子进程是,内核将子进程的退出状态传递给父进程,然后抛弃已经终止的进程。

父进程通过调用waitpid函数来等待它的子进程终止或者停止。每个waitpid函数对应一个等待集合。

 #include <sys/types.h>
 #include <sys/wait.h>

pid_t waitpid(pid_t pid, int *status, int options);


如果pid>0,等待集合就是一个单独的子进程,它的进程ID等于pid,

如果pid=-1,等待集合就是由父进程所有的子进程组成。


option默认为0,决定waitpid的操作,默认情况下,waitpid挂起调用进程的执行,直到它的等待集合中的一个子进程终止。waitpid返回已经终止的子进程的PID,并将这个已终止的子进程从系统中去除。


如果staus非空,则waitpid会在参数status中放上关于导致返回的子进程的状态信息。可以通过如下的几个宏定义,判断status的状态信息。

(1)WIFEXITED(status):如果子进程通过调用exit或者返回正常终止,则返回真

(2)WEXITSTATUS(status):返回一个正常终止的子进程的退出状态

(3)WIFSIGNALED(status):如果子进程接收到一个默认行为是终止进程的信号而终止的,则返回真

(4)WTERMSIG(status):如果子进程是因为信号的原因终止,则返回信号的编号

(5)WIFSTOPPED(status):如果引起返回的子进程当前是被停止的,则返回真

(6)WSTOPSIG(status):返回引起子进程终止的信号的数量


错误条件:

如果调用进程没有子进程,则waitpid返回-1,并且设置errno为ECHILD

如果waitpid函数被一个信号中断,则返回-1,并设置errno为EINTR


例城:

#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
#include<sys/wait.h>
#include<stdlib.h>
#include<errno.h>    /**errno定义在errno.h中  */
#include<string.h>   /**strerror定义在string.h中  */
#define N 2
int main()
{
    int status, i;
    pid_t pid[N],retpid;

    for(i=0;i<N;i++)
    {
        if((pid[i]=fork())==0)
        {
            exit(100+i);
        }
    }

    i = 0;
    while((retpid=waitpid(pid[i++],&status,0))>0)
    {
        if(WIFEXITED(status))
        {
            printf("child %d terminated normally with exit status=%d\n",retpid,WEXITSTATUS(status));
        }
        else
        {
            printf("child %d terminated abnormally\n",retpid);
        }
    }

    if(errno != ECHILD)
    {
        fprintf(stderr,"fork error :%s\n",strerror(errno));
    }
        exit(0);
    
}


运行结果:

child 4423 terminated normally with exit status=100
child 4424 terminated normally with exit status=101


版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

深入理解计算机系统(第二版) 家庭作业 第八章

8.9 进程对 是否并发 AB No AC Yes AD Yes ...

阅读深入理解计算机系统(二)--------------- 进程控制

1.     进程控制 每个进程都有一个唯一的正数进程ID,getpid()函数可以获得调用者的进程ID。 a.     fork()函数: 创建一个新的运行子进程,新创建的子进程几乎但不完全与父进程...

《深入理解计算机系统》笔记(五)并发、多进程和多线程【Final】

该书中第11章是写web服务器的搭建,无奈对web还比较陌生。还没有搞明白。     这些所谓的并发,其实都是操作系统做的事情,比如,多进程是操作系统fork函数实现的、I/O多路复用需要内核挂起进程...

《深入理解计算机系统》笔记(四)虚拟存储器,malloc,垃圾回收【插图】

概述         ●我们电脑上运行的程序都是使用虚拟存储,跟物理内存根本不搭边。         ●既然虚拟内存是在磁盘上的,为什么它又运行这么好,并没有感觉卡顿?这要感谢程序的局部性! ...

《深入理解计算机系统》笔记(三)链接知识【附图】

概述         ●该章节主要讲解的是ELF文件的结构。             ●静态库的概念       &#...

深入理解计算机系统-之-数值存储(三)-- 原码、反码、补码和移码详解

原码 如果机器字长为n,那么一个数的原码就是用一个n位的二进制数,其中最高位为符号位:正数为0,负数为1。剩下的n-1位表示概数的绝对值。PS:正数的原、反、补码都一样:0的原码跟反码都有两个,因为...

阅读深入理解计算机系统(三)--------------- 虚拟存储器

一、碎片现象:造成堆利用率低的主要原因是一种碎片现象。         内部碎片:已分配块比有效载荷大时发生的。         外部碎片:是当空闲存储器合计起来满足分配请求,但是没有一个单独的空...

深入理解计算机系统之链接(三)

静态库的概念静态库就是由一组独立的可重定向目标文件封装而成的,在Unix系统中,静态库以一种称为归档(archive)的特殊文件存放在磁盘上。存档文件是一组连接起来的可重定位目标文件的集合,有一个头部...

《深入理解计算机系统》(三)

C只支持大小在编译时就能知道的多维数组(对于第一维可能有些例外)。在许多应用程序中,我们需要代码能够动态分配的任意大小的数组进行操作。,为此,我们必须显示地写出从多维数组到一维数组的映射。 异类的数...

《深入理解计算机系统》读后笔记三——“第六章 存储器层次结构”

第六章——存储器层次结构          1、存储器层次结构               看这一章,首先了解存储器层次结构是什么。     ...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)