分类: LINUX
2016-11-29 11:33:21
原文地址:wait()/waitpid系统调用 作者:zhenhuaqin
zombie不占用内存也不占用CPU,表面上我们可以不用在乎它们的存在,然而事实上UNIX系统限制了某一时刻能同时存在的进程的最大数目。如果程序不及时清理系统中的zombie,最终会导致进程数过多,当再次需要产生新进程时就会出错。
鉴于上边的原因,我们需要在子进程调用exit后在父进成中调用wait或waipid
#include
#include
pid_t wait(int &statloc);
pid_t waitpid(pid_t pid,int *statloc, int options);
Both return:process ID if OK,
-1 on error
它们被父进程调用以获取子进程结束信息、清除zombie。当父进程调用这两个函数时
a 阻塞(如果它的子进程还在运行)
b 立即返回子进程结束信息(如果一个子进程已经结束并等待父进程获取信息)
c 返回错误(如果不存在子进程)
当一个进程的子进程exit后,自己可以通过wait系统调用获取子进程的exit status。
pid = wait(stat_addr);
pid是exit子进程的进程ID,stat_addr是本进程用户空间的一个变量,用于存放exit子进程的exit status。
当wait执行时,内核搜寻本进程的zombie子进程,如果本进程没有子进程,则返回error。否则,提取子进程的进程进程ID和exit status。同时,内核将计算子进程的执行时间(user mode 和 kernel mode),记录到本进程u area的相应field中,然后释放子进程占有的process table slot。
2.二者的区别:
两个函数的不同在于wait会令调用者阻塞直至某个子进程终止而waitpid则可以通过设置一个选项来设置为非阻塞,另外waitpid并不是等待第一个结束的进程而是等待参数中pid指定的进程。
两个函数中的变量statloc是一个指向int型数据的指针。如果此变量不是NULL,则结束的进程的termination status会被保存在statiloc所指向的内存的区域;如果我们不关心termination status,则可以把statloc置为NULL。
传统的实现中这两个函数返回的整数中特定的比特位被赋予了特定的含义。
POSIX.1指定了一些包含在头文件
Macro Description
WIFEXITED(status) 如果status是由一个正常结束的进程产生的则值为真, 此时我们可以继续使用宏
WEXITSTATUS(status) 来获取exit或_exit的参数
WIFSIGNALED(status) 如果status是由一个异常结束(接受到一个信号)的进 程产生的则值为真,此时使用宏WTERMSIG(status)来 获取信号数。
WIFSTOPPED(status) 如果status是由一个接受到信号目前终止的进程产生的 则值为真,此时可以继续调用宏WSTOPSIG(status)来 查看是哪个信号导致进程终止。
waitpid的option常量
WNOHANG waitpid将不阻塞如果指定的pid并未结束
WUNTRACED 如果子进程进入暂停执行情况则马上返回,但结束状态不予以理会。
waitpid中pid的含义依据其具体值而变
pid==-1 等待任何一个子进程,此时waitpid的作用与wait相同
pid >0 等待进程ID与pid值相同的子进程
pid==0 等待与调用者进程组ID相同的任意子进程
pid<-1 等待进程组ID与pid绝对值相等的任意子进程
waitpid提供了wait所没有的三个特性:
1 waitpid使我们可以等待指定的进程
2 waitpid提供了一个无阻塞的wait
3 waitpid支持工作控制
具体可以查看APUE page202