当一个进程完成了最后的语句,他就会终止,并使用系统调用exit()请求删掉它。

进程终止时,进程可以返回状态值(通常是整数)到父进程(通过wait()系统调用)。

进程的所有的资源------包括物理的和虚拟的内存,打开的文件以及I/O缓存-------会被操作系统回收。

在其他情况下也会出现进程终止。进程可以通过适当的系统调用来终止其他的进程(比如Window的TermainateProcess()).通常是带终止的进程的父进程才能执行这一列调用。否则,用户可以任意的终止彼此的作业。如果父进程要终止其子进程,那么需要知道其子进程的标识符。因此当一个进程创建了一个子进程时候,新创建的进程的标识符会传递给父进程。

父进程可能会因为下面的原因终止子进程:

  • 子进程使用了超过它所分配的资源(要确定这是否发生,父进程必须有检查子进程状态的机制)
  • 分配给子进程的任务已经不再需要
  • 父进程退出,操作系统不会允许子进程苟活的!!

当父进程终止了,一些操作系统不允许子进程继续存在。这样的系统中,如果进程终止(不管是正常的还是异常的),它的所有的子进程都必须被终止。这一现象,称为级联终止(cascading termination),通常是由操作系统发起的。

为了说明进程执行和终止,我们这样考虑,,在UNIX或者Linux系统中,我们可以使用exit()系统调用,并提供一个退出状态作为参数,来终止一个进程:

exit(1);

事实上,在正常终止时候,exit()可能直接(比如上面代码的这样)或者间接的(在main()中返回语句)的被调用。

父进程可能使用wait()系统调用来等待子进程的终止。参数status用来允许父进程收集子进程退出时候的状态。这个系统代用当然会返回终止的子进程的进程标识符PID,所以父进程就可以断定是那个子进程终止了。

pid t pid;
int status;
pid = wait(&status);

当一个进程终止了,它的资源会由操作系统回收。

然而,它在进程表中的条目必须保留,直到父进程调用wait(),因为进程表包含进程的退出状态。

已经终止的进程,但其父进程尚未调用wait()的进程被称为僵尸(zombie)程序。所有进程在它们终止的时候都转换到这个状态。但通常它们只是简单地作为僵尸程序存在。一旦父进程调用wait(),僵尸进程的进程标识符和它在进程表中的的条目都会被释放。

现在来考虑,当父进程没有调用wait()而是终止了,这会发生什么呢?这会使得子进程变成一个孤儿(orphans)。Linux和UNIX通过将init进程分配给孤儿进程作为其新的父进程来处理这个场景。init进程会周期的调用wait(),从而允许收集任何孤儿进程的退出状态,并释放孤儿进程标识符和相应的进程表条目。

results matching ""

    No results matching ""