• 8.5 exit函数进程控制


    8.5 exit函数-进程控制

    如同7 . 3节所述,进程有三种正常终止法及两种异常终止法。

    (1) 正常终止:

    a)     main函数内执行return语句。如在7 . 3节中所述,这等效于调用exit

    b)     调用exit函数。此函数由ANSI C定义,其操作包括调用各终止处理程序(终止处理程序在调用a t exit函数时登录),然后关闭所有标准I / O流等。因为ANSI C并不处理文件描述符、多进程(父、子进程)以及作业控制,所以这一定义对UNIX系统而言是不完整的。

    c)     调用_ exit_Exit系统调用函数。此函数由exit调用,它处理UNIX特定的细节。_ exit是由POSIX.1说明的。其目的是为进程提供一种无需运行终止处理程序或信号处理程序而终止的方法。对标准IO流是否进行冲洗,这取决于实现。在UNIX系统中,两个函数是同义的,并不清洗IO流。

    d)     进程的最后一个线程在其启动例程中执行返回语句。但是,该线程的返回值不会用作进程的返回值。当最后一个线程从其启动例程返回时,该进程以终止状态0返回;

    e)     进程的最后一个线程调用pthread_exit函数。如同前面一样,在这要那个情况中,进程终止状态总是0,这与传送给pthread_exit的参数无关。

    (2) 异常终止:

    a)     调用abort。它产生S I G A B RT信号,所以是下一种异常终止的一种特例。

    b)     当进程接收到某个信号时。(第1 0章将较详细地说明信号。)进程本身(例如调用abort函数)、其他进程和内核都能产生传送到某一进程的信号。例如,进程越出其地址空间访问存储单元,或者除以0,内核就会为该进程产生相应的信号。

    c)     最后一个线程对取消cancellation请求做出响应。按系统默认,取消以延迟方式发生:一个线程要求取消另一个线程,一段时间以后,目标线程终止。

     

    不管进程如何终止,最后都会执行内核中的同一段代码。这段代码为相应进程关闭所有打开描述符,释放它所使用的存储器等等。

    对上述任意一种终止情形,我们都希望终止进程能够通知其父进程它是如何终止的。对于exit_ exit,这是依靠传递给它们的退出状态( exit status)参数来实现的。在异常终止情况,内核(不是进程本身)产生一个指示其异常终止原因的终止状态( termination status)。在任意一种情况下,该终止进程的父进程都能用waitwaitpid函数(在下一节说明)取得其终止状态。

    注意,这里使用了“退出状态”(它是传向exit_ exit的参数,或main的返回值)和“终止状态”两个术语,以表示有所区别。在最后调用_ exit时内核将其退出状态转换成终止状态(回忆图7 - 1)。下一节中的表8 - 1说明了父进程检查子进程的终止状态的不同方法。如果子进程正常终止,则父进程可以获得子进程的退出状态。

    在说明fork函数时,一定是一个父进程生成一个子进程。上面又说明了子进程将其终止状态返回给父进程。但是如果父进程在子进程之前终止,则将如何呢?其回答是对于其父进程已经终止的所有进程,它们的父进程都改变为init进程。我们称这些进程由init进程领养。其操作过程大致是:在一个进程终止时,内核逐个检查所有活动进程,以判断它是否是正要终止的进程的子进程,如果是,则该进程的父进程I D就更改为1 ( init进程的I D )。这种处理方法保证了每个进程有一个父进程

    另一个我们关心的情况是如果子进程在父进程之前终止,那么父进程又如何能在做相应检查时得到子进程的终止状态呢?对此问题的回答是内核为每个终止子进程保存了一定量的信息,所以当终止进程的父进程调用waitwaitpid 时,可以得到有关信息。这种信息至少包括进程I D、该进程的终止状态、以反该进程使用的CPU时间总量。内核可以释放终止进程所使用的所有存储器,关闭其所有打开文件。在UNIX术语中,一个已经终止、但是其父进程尚未对其进行善后处理(获取终止子进程的有关信息、释放它仍占用的资源)的进程被称为僵死进程( zombiep s ( 1 )命令将僵死进程的状态打印为Z。如果编写一个长期运行的程序,它fork了很多子进程,那么除非父进程等待取得子进程的终止状态,否则这些子进程就会变成僵死进程。

    最后一个要考虑的问题是:一个由init进程领养的进程终止时会发生什么?它会不会变成一个僵死进程?对此问题的回答是“”,因为init被编写成只要有一个子进程终止, init就会调用一个wait函数取得其终止状态。这样也就防止了在系统中有很多僵死进程。当提及“一个init的子进程”时,这指的是init直接产生的进程(例如,将在9 . 2节说明的g e t t y进程),或者是其父进程已终止,由init 领养的进程

  • 相关阅读:
    转移到新的个人独立博客。
    hdu5618 (三维偏序,cdq分治)
    平衡树维护动态凸包
    poj1986 LCA
    hdu2586 LCA
    LCA最近公共祖先 ST+RMQ在线算法
    hdu 3401 单调队列优化DP
    【转】单调队列优化DP
    CodeForces 548D 单调栈
    hdu3530 单调队列
  • 原文地址:https://www.cnblogs.com/shaoguangleo/p/2806015.html
Copyright © 2020-2023  润新知