zoukankan      html  css  js  c++  java
  • 进程控制之exit函数

    进程有下面5种正常终止方式:

    (1)在main函数内执行return语句。这等效于调用exit。

    (2)调用exit函数。此函数有ISO C定义,其操作包括调用各终止处理程序(终止处理程序在调用atexit函数时登记),然后关闭所有标准I/O流等。

    (3)调用_exit或_Exit函数。ISO C定义_Exit,其目的是为进程提供一种无需运行终止处理程序或信号处理程序而终止的方法。对标准I/O流是否进行冲洗,这取决于实现。在UNIX系统中,_Exit和_exit是同义的,并不清洗标准I/O流。_exit函数由exit调用,它处理UNIX特定的细节。

    在大多数UNIX系统实现中,exit(3)是标准C库中的一个函数,而_exit(2)则是一个系统调用。

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

    (5)进程的最后一个线程调用pthread_exit函数。在这种情况下,进程终止状态总是0,这与传送给pthread_exit的参数无关。

    三种异常终止方式如下:

    (1)调用abort。它产生SIGABRT信号,这是下一种异常终止的特例。

    (2)当进程接收到某些信号时。信号可由进程自身(例如调用abort函数)、其他进程或内核产生。

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

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

    对于上述任意一种终止情形,我们都希望终止进程能够通知其父进程它是如何终止的。对于三个终止函数(exit、_exit和_Exit),实现这一点的方法是,将其退出状态(exit status作为参数传递给函数。在异常终止情况下,内核(不是进程本身)产生一个指示其异常终止原因的终止状态(termination status)。在任意一种情况下,该终止进程的父进程都能用wait或waitpid函数取得其终止状态。

    注意,这里使用了“退出状态”(它是传向exit或_exit的参数,或main的返回值)和“终止状态”两个术语,以表示有所区别。在最后调用_exit时,内核将退出状态转换成终止状态(回忆图7-1http://www.cnblogs.com/nufangrensheng/p/3507921.html)。如果子进程正常终止,父进程可以获得子进程的退出状态。

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

    另一个我们关心的情况是如果子进程在父进程之前终止,那么父进程又如何能在做相应检查时得到子进程的终止状态呢?对此问题的回答是:内核为每个终止子进程保存了一定量的信息,所以当终止进程的父进程调用wait或waitpid时,可以得到这些信息。这些信息至少包括进程ID、该进程的终止状态、以及该进程使用的CPU时间总量。内核可以释放终止进程所使用的所有存储区,关闭其所有打开文件。在UNIX术语中,一个已经终止,但是其父进程尚未对其进行善后处理(使用wait获取终止子进程的有关信息,释放它仍占用的资源)的进程称为僵死进程(zombie)(更多关于僵尸进程可参考:http://www.cnblogs.com/bettercoder/p/3501086.html)。ps(1)命令将僵死进程的状态打印为Z。如果编写一个长期运行的程序,它调用fork产生了很多子进程,那么除非父进程等待取得子进程的终止状态,否则这些子进程终止后就会变成僵死进程。

    最后一个要考虑的问题是:一个由init进程领养的进程终止时会发生什么?它会不会变成一个僵死进程?对此问题的回答是:“否”,因为init被编写成无论何时只要有一个子进程终止,init就会调用wait函数取得其终止状态。这样也就防止了在系统中有很多僵死进程。当提及“一个init的子进程”时,这指的可能是init直接产生的进程,也可能是其父进程已终止,由init领养的进程。

    本篇博文内容摘自《UNIX环境高级编程》(第二版),仅作个人学习记录所用。关于本书可参考:http://www.apuebook.com/

  • 相关阅读:
    python函数
    python文件IO操作
    LAMP项目上线
    linux下的小工具
    linux下自有服务
    Lesson_Swift2
    枚举
    使用文件流下载附件
    Global中的Timer计时器
    IE11下的NPOI导出提示__doPostBack未定义解决方案
  • 原文地址:https://www.cnblogs.com/nufangrensheng/p/3509618.html
Copyright © 2011-2022 走看看