进程即将结束源代码链接地址
进程结束后资源处理的问题
每一个进程结束之后都会涉及到资源清理的问题:
资源一:操作系统会回收你的进程中涉及到资源(堆(
malloc
)、栈、文件IO);资源二:进程建立时会自动产生一个
task_struct
大小8KB,这个就是你当前进程包含所有信息的一个结构体(来自于父进程)。这个结构体(相当于文件描述符),他是进程描述符。存在于进程管理表中。这里的资源(进程运行也需要栈:进程计数器)操作系统无法回收。只能有他的父进程回收。
僵尸进程
前情提要:
子进程先结束。父进程(父进程知道子进程已经结束了),不一定立刻给这个子进程”收尸”,父子进程间(回收资源)是异步通信的。子进程已亡,父进程尚未给其“收尸”,此时这个进程就是僵尸进程。子进程此刻只有task_struct(8KB)和进程运行的栈,未被释放。
回收资源:
回收一:父进程可以调用
wait
和waitpid
对子进程的资源进行回收。回收二:linux设计时,如果没有通过函数(
wait
和waitpid
)进行回收子进程资源,父进程在自己结束后会,自动释放子进程资源。
孤儿进程
前情提要:
父进程先于子进程结束,此时子进程就是一个孤儿进程(尚未结束),这个子进程就会被
init1
(进程1)收养,相当于子进程有了父亲。
wait
和watitpid
(1)、子进程先结束,会发一个信号SIGCHLD
,宏定义是:17。
(2)、父进程调用wait
来收尸,如果子进程没有结束,就一直在这里等待,阻塞在这里。
(3)、信号发给父进程,此时就可以回收(僵尸进程),父进程可以及时回收资源。如果没有资源回收函数,什么时候回收资源,父进程安排,因为通信是异步通信。
(4)、父进程没有子进程的情况,wait
,返回值错误。
PS:子进程、父进程、谁先运行,不规定。一旦有了父wait
,肯定是我们的子进程先结束。
wait
函数
wait
函数查看上一篇博客。
WIFEXITED测试进程是否正常退出(return、 exit、_exit):逻辑值(真、假)
WIFEXITED(status)//测试程序退出是否正正确退出(return、 exit、 _exit):逻辑值(真、假)
returns true if the child terminated normally, that is, by call‐
ing exit(3) or _exit(2), or by returning from main().
WEXITSTATUS(status)//测试子程序结束的返回值,返回值是无符号字符型函数
returns the exit status of the child. This consists of the
least significant 8 bits of the status argument that the child
specified in a call to exit(3) or _exit(2) or as the argument
for a return statement in main(). This macro should be employed
only if WIFEXITED returned true.
WIFSIGNALED(status)//判断是不是被signal信号终止的(外界的信号终止的,非正常终止)
returns true if the child process was terminated by a signal.
waitpid
函数
(1)、回收子进程资源;
(2)、可以指定特定的pid
值(特定进程);
(3)、设置阻塞或者非阻塞模式。
//头文件
#include <sys/types.h>
#include <sys/wait.h>
//函数原型
pid_t wait(int *status);
pid_t waitpid(pid_t pid, int *status, int options);//options设置函数阻塞或者非阻塞模式
int waitid(idtype_t idtype, id_t id, siginfo_t *infop, int options);
options参数
//0(零), 阻塞模式
The value of options is an OR of zero or more of the following constants:
//不阻塞模式
WNOHANG return immediately if no child has exited.
//基本不用
WUNTRACED also return if a child has stopped (but not traced via ptrace(2)). Status for traced children which have stopped is provided
even if this option is not specified.
//基本不用
WCONTINUED (since Linux 2.6.10)
also return if a stopped child has been resumed by delivery of SIGCONT.
pid参数
The value of pid can be:
//关于进程族的,不涉及
< -1 meaning wait for any child process whose process group ID is equal to the absolute value of pid.
//任意一个子进程,回收任意的pid waitpid(-1, NULL, 0);
-1 meaning wait for any child process.
//涉及子进程,不说
0 meaning wait for any child process whose process group ID is equal to that of the calling process.
//等待指定的子进程的pid成功返回子进程的pid 回收指定的子进程pid waitpid(child_pid, NULL, 0);
//如果没有这个子进程的pid,阻塞的回收资源函数就不阻塞了,运行返回错误值,继续下面的父进程的代码。
> 0 meaning wait for the child whose process ID is equal to the value of pid.
//返回值
wait(): on success, returns the process ID of the terminated child; on error, -1 is returned.
waitpid(): on success, returns the process ID of the child whose state has changed; if WNOHANG was specified