unix进程控制 exit函数

一:进程退出函数详解

在前一篇的 Unix进程环境之---进程结束的方式和退出函数 中提到了Unix程序退出的八中方式,分别为:

1:从  main  函数返回

2:调用  exit  函数

3:调用  _exit  函数或者是  _Exit  函数

4:从最后一个线程中返回

5:从最后一个线程中调用  pthread_exit

还有三种非正常的结束方式:

6:调用  abort

7:接收到信号

8:应答最后一个线程的取消请求

以下就各个函数做比较详细的解释:

1:执行return从main函数返回等同于调用exit函数。

2:调用exit函数,这个函数有ISO C所定义,包括调用调用所有的被atexit注册过的退出处理程序和关闭所有的标准I/O流。因为ISO C不会处理文件描述符、多进程、作业控制,所以在Unix系统中,这个函数的定义有些不完整。

3:ISO C定义了一个_Exit函数来提供进程结束时,不用执行退出处理程序和信号处理 程序。在Unix系统中,_Exit和_exit同义,都不用 刷新标准I/O流  _exit函数由POSIX.1所定义。  

在大多数 Unix系统中exit函数是标准的C库函数,_exit是系统调用。

4:线程的返回值不作为进程的返回值,当最后一个线程从例程返回时,进程结束时的结束状态值为0。

5:和4中的一样,这种情况下同样返回0,与传递到pthread_exit函数中的参数无关。

不管一个进程如何结束,内核都会为这个结束的进程关闭所有的打开的件描述符,释放所利用的内存,等等。

如果我们想要结束的进程通知父进程自己是如何结束的,对于exit 、 _Exit和_exit ,通过传递退出状态值,作为函数的参数来实现。

对于非正常的结束方式,有内核,而不是结束进程,生成一个结束状态值来指示非正常结束的原因。这时,父进程可以通过 wait和waitpid函数 来获取结束进程的结束状态值。

二:为什么任何一个进程都有父进程

当调用一个fork函数后,子进程就会有一个父进程。当父进程先于子进程结束时,init进程会成为这个子进程的父进程。

具体的实现如下,通常情况下,在一个进程结束时,内核会遍历所以的活动进程,看是否有结束进程的子进程。如果有这个进程Parent PID值,修改为1(init进程的PID),这样保证了所以的进程都有父进程。

三:僵死进程的产生

在子进程先于父进程结束的情况下,当父进程要检查一个子进程是否结束时,子进程完全消失了,这是父进程不能取得结束子进程的结束状态信息。

在一个进程结束时,内核会保存保存每个结束进程的少量信息。这些信息最少包含,进程ID,结束状态值,进程利用的CPU时间。

当父进程调用wait或者是waitpid时,可以利用这些结束信息。

僵死进程 产生的原因,在Unix系统术语中,如果一个进程结束了,而父进程没有等待他(wait),成为僵死进程。

如果我们写一个长时间运行的程序,在这个程序中fork了很多子进程,如果父进程没有wait和取得他们的结束状态值,那么他们会成为僵死进程。

如果一个进程继承了init,那么他是否会成为僵死进程,答案是否定的。因为init的任何一个子进程结束时,init会调用wait函数来取得结束状态值。从而避免僵死进程的产生。

从上可以看出,在 子进程先于父进程 结束,而父进程没有wait这个子进程才会产生僵死进程。


你可能感兴趣的:(unix,exit,进程控制)