`
Speeddsy
  • 浏览: 24695 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

wait和waitpid详解

 
阅读更多

wait和waitpid详解


wait的函数原型是:  
#include <sys/types.h>
#include <sys/wait.h>

pid_t wait(int *status);   

进程一旦调用了wait,就立即阻塞自己,由wait自动分析是否当前进程的某个子进程已经退出,如果让它找到了这样一个已经变成僵尸的子进程, wait就会收集这个子进程的信息,并把它彻底销毁后返回;如果没有找到这样一个子进程,wait就会一直阻塞在这里,直到有一个出现为止。    

参数status用来保存被收集进程退出时的一些状态信息,它是一个指向int类型的指针。但如果我们对这个子进程是如何死掉的毫不在意,只想把这个僵尸进程消灭掉,(事实上绝大多数情况下,我们都会这样想),我们就可以设定这个参数为NULL,就象这样:pid = wait(NULL);

如果成功,wait会返回被收集的子进程的进程ID,如果调用进程没有子进程,调用就会失败,此时wait返回-1,同时errno被
置为ECHILD。 


--------------------------------------------------
--------------------------------------------------

waitpid的函数原型是:
#include <sys/types.h>
#include <sys/wait.h>

pid_t waitpid(pid_t pid, int *status, int options);

从本质上讲,系统调用waitpid和wait的作用是完全相同的,但waitpid多出了两个可由用户控制的参数pid和options,从而为我们编程提供了另一种更灵活的方式。

下面我们就来详细介绍一下这两个参数:     
● pid     
从参数的名字pid和类型pid_t中就可以看出,这里需要的是一个进程ID。但当pid取不同的值时,在这里有不同的意义。 
pid>0时,只等待进程ID等于pid的子进程,不管其它已经有多少子进程运行结束退出了,只要指定的子进程还没有结束,waitpid就会一直等下去。  
pid=-1时,等待任何一个子进程退出,没有任何限制,此时waitpid和wait的作用一模一样。
pid=0时,等待同一个进程组中的任何子进程,如果子进程已经加入了别的进程组,waitpid不会对它做任何理睬。 pid<-1时,等待一个指定进程组中的任何子进程,这个进程组的ID等于pid的绝对值。   

● options   
ptions提供了一些额外的选项来控制waitpid,目前在Linux中只支持WNOHANG和WUNTRACED两个选项,这是两个常数,可以用"|"运算符把它们连接起来使用,比如:
ret=waitpid(-1,NULL,WNOHANG | WUNTRACED);   
如果我们不想使用它们,也可以把options设为0,如:   
ret=waitpid(-1,NULL,0);
如果使用了WNOHANG参数调用waitpid,即使没有子进程退出,它也会立即返回,不会像wait那样永远等下去。
而WUNTRACED参数,由于涉及到一些跟踪调试方面的知识,加之极少用到,这里就不多费笔墨了,有兴趣的读者可以自行查阅相关材料。  


-------------------------------------------------------
-------------------------------------------------------
  
看到这里,聪明的读者可能已经看出端倪了--wait不就是经过包装的waitpid吗?
没错,察看<内核源码目录>/include/unistd.h文件349-352行就会发现以下程序段:

static inline pid_t wait(int *wait_stat)
{
return waitpid(-1, wait_stat, 0);
} /*返回值和错误*/     


waitpid的返回值比wait稍微复杂一些,一共有3种情况:  
● 当正常返回的时候,waitpid返回收集到的子进程的进程ID;
● 如果设置了选项WNOHANG,而调用中waitpid发现没有已退出的子进程可收集,则返回0;      
● 如果调用中出错,则返回-1,这时errno会被设置成相应的值以指示错误所在;当pid所指示的子进程不存在,或此进程存在,但不是调用进程的子进程,waitpid就会出错返回,这时errno被设置为ECHILD 。

其它: 调用 wait&waitpid 来处理终止的子进程:
pid_t wait(int * statloc);
pid_t waitpid(pid_t pid,int *statloc, int options);
两个函数都返回两个值:函数的返回值和终止的子进程ID,而子进程终止的状态则是通过statloc指针返回的。

wait&waitpid 的区别是显而易见的,wait等待第一个终止的子进程,而waitpid则可以指定等待特定的子进程。这样的区别可能会在下面这种情况时表现得更加明显:
当同时有5个客户连上服务器,也就是说有五个子进程分别对应了5个客户,此时,五个客户几乎在同时请求终止,这样一来,几乎同时,五个FIN发向服务器,同样的,五个SIGCHLD信号到达服务器,然而,UNIX的信号往往是不会排队的,显然这样一来,信号处理函数将只会执行一次,残留剩余四个子进程作为僵尸进程驻留在内核空间。此时,正确的解决办法是利用waitpid(-1, &stat, WNOHANG)防止留下僵尸进程。其中的pid为-1表明等待第一个终止的子进程,而WNOHANG选择项通知内核在没有已终止进程项时不要阻塞。


wait&waitpid 区别 :
waitpid提供了wait函数不能实现的3个功能: waitpid等待特定的子进程, 而wait则返回任一终止状态的子进程; waitpid提供了一个wait的非阻塞版本; waitpid支持作业控制(以WUNTRACED选项). 用于检查wait和waitpid两个函数返回终止状态的宏: 这两个函数返回的子进程状态都保存在statloc指针中, 用以下3个宏可以检查该状态:

WIFEXITED(status): 若为正常终止, 则为真. 此时可执行WEXITSTATUS(status): 取子进程传送给exit或_exit参数的低8位.
WIFSIGNALED(status): 若为异常终止, 则为真.此时可执行 WTERMSIG(status): 取使子进程终止的信号编号.
WIFSTOPPED(status): 若为当前暂停子进程, 则为真. 此时可执行 WSTOPSIG(status): 取使子进程暂停的信号编号
分享到:
评论

相关推荐

    详解C语言中的wait()函数和waitpid()函数

    C语言wait()函数:结束(中断)进程函数(常用) 头文件: #include &lt;sys&gt; #include 定义函数: pid_t wait (int * status); 函数说明:wait()会暂时停止目前进程的... 子进程的结束状态值请参考waitpid(). 返回值:

    waitpid和wait

    从本质上讲,系统调用waitpid和wait的作用是完全相同的,但waitpid多出了两个可由用户控制的参数pid和options,从而为我们编程提供了另一种更灵活的方式。下面我们就来详细介绍一下这两个参数

    深入浅出---unix多进程编程之wait()和waitpid()函数

    现在要知道调用wait或waitpid的进程可能会发生什么情况:如果进程由于接收到SIGCHLD信号而调用wait,则可期望wait会立即返回。但是如果在任意时刻调用wait则进程可能会阻塞。两个函数原型#include&lt;sys&gt;pid_twait(int...

    【Linux】进程二 (PCB & fork/vfork & wait/waitpid & exit/_exit & exec函数族 & 环境变量)

    一、描述进程——PCB ·进程信息被放在一个叫做进程控制块的数据结构中,可以理解为进程属性的集合 ·我们称为PCB,Linux操作系统下的PCB是:task struct 2、task_struct——PCB的一种 ·在Linux中描述进程的结构体...

    深入探讨:unix多进程编程之wait()与waitpid()函数

    本篇文章是对unix多进程编程中的wait函数与waitpid函数的使用进行了详细的分析介绍,需要的朋友参考下

    Perl waitpid帮助

    一个关于Perl Waitpid的帮助信息,就是用Man之类的工具打印的那部分信息。其实可以联机看,只是存下来方便一点。

    Linux进程控制编程-waitpid函数实例.pdf

    Linux进程控制编程-waitpid函数实例.pdf 学习资料 复习资料 教学资源

    UNIX环境高级编程(第八章)

    8.6 wait和waitpid函数 148 8.7 wait3和wait4函数 152 8.8 竞态条件 153 8.9 exec函数 156 8.10 更改用户ID和组ID 160 8.10.1 setreuid 和setregid函数 162 8.10.2 seteuid和 setegid函数 163 8.10.3 组ID 163 8.11 ...

    大部分代码,关于创建与回收进程

    文件中包含本博客中的大部分代码,以及其他代码供读者取用,可以在Linux上运行,感受fork、wait、waitpid函数的作用

    12_waitpid.c

    针对进程中出现的僵尸进程,运用wait()函数,父进程等待子进程,解决僵尸进程的出现。

    linuxwait与waitpid函数的深入分析[参考].pdf

    linuxwait与waitpid函数的深入分析[参考].pdf

    大厂公司-招聘笔记.pdf

    公司招聘笔记,大厂面试知识总结。 TCP 状态转换图 操作系统 进程间通信方式.......................................................................................wait 和 waitpid 区别......................

    什么是PHP7中的孤儿进程与僵尸进程

    当一个 进程完成它的工作终止之后,它的父进程需要调用wait()或者waitpid()系统调用取得子进程的终止状态。 孤儿进程 一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程。孤儿进程将...

    详解linux下避免僵尸进程的几种方法

    linux下我们可以调用fork...1.在fork后调用wait/waitpid函数取得子进程退出状态。 2.调用fork两次(第一次调用产生一个子进程,第二次调用fork是在第一个子进程中调用,同时将父进程退出(第一个子进程退出),此时的第

    linux waitpid检测子进程是否退出

    fork 创建子进程,由父进程检测子进程是否退出,子进程退出后重新启动。

    perl函数手册(英文版)

    进程:alarm, die, dump, exec, exit, fork, getlogin, getpgrp, getppid, getpriority, kill, setpriority, sleep, system, times, umask, wait, waitpid 协议:endprotent, getprotobyname, getprotobynumber, ...

    操作系统实验五-进程间通信-管道通信

    操作系统实验五 进程间通信——管道通信 无名管道 有名管道 write()和read() pipe() 函数int pipe(int fd[2])创建一个管道 lockf()函数使用管道通信时,可关闭某些不需要的读或写描述符wait()、waitpid(),sys/wait....

Global site tag (gtag.js) - Google Analytics