由于linux是一个多用户的操作系统,在同一时间可能会有多个用户争夺系统资源,进程为了及时,及早的完成任务(得到系统资源)就创建了子进程来争夺系统资源。一旦子进程用fork()创建成功,父子进程就会一起从fork处继续执行【例1】,两个进程相互争夺系统资源。
我们希望子进程继续执行,这个时候就得让父进程挂起,直到子进程完成任务,那么在这种情况下我们就得用函数wait或者waitpid来帮助了。
例1:
#include <stdio.h>
#include <unistd.h>
int main ()
{
pid_t pid;
printf("Before create child process;\n");
pid=fork();
printf("After create child process.\n");
return 0;
}
输出结果:
Before create child process.
After create child process.
After create child process.
我们都知道,unix系统限制了某一时刻能同时存在进程的最大数目,如果不及时清理系统中的僵死进程【一个已经终止,但是其父进程尚未对其进行善后处理(获取终止子进程的有关信息,释放它仍占用的资源)的进程:zombie。调用fork两次以避免僵死进程】,那么再次产生新的进程时,可能产生错误。由于这些原因一般在子进程中调用exit之后在父进程中调用wait或者waitpid函数。父进程调用这两个函数之后会获取子进程的结束信息,进行相关的清理动作。
引用:《unix环境高级编程》,调用这两个函数之后产生下面的情况:
A:阻塞(如果它的子进程还在运行)
B:立即返回子进程结束信息(如果一个子进程已经结束并等待父进程获取信息)
C:如果没有任何子进程,则立即出现错误返回。
这两个函数的区别:
1:在一个子进程终止前,wait使其调用者阻塞,而waitpid有一个选项,可使调用者不阻塞。
2:另外waitpid并不是等待第一个结束的进程而是等待参数中pid指定的进程。
waitpid的option常量
A:WNOHANG waitpid将不阻塞如果指定的pid并未结束
B:WUNTRACED 如果子进程进入暂停执行情况则马上返回,但结束状态不予以理会。
waitpid提供了wait没有提供的三个功能:
1:waitpid可等待一个特定的进程,而wait则返回任一终止子进程的状态【如果一个子进程已经终止,并且是一个僵死进程,则wait立即返回并取得该子进程的状态,否则wait使其调用者阻塞直到一个子进程终止。如果调用者阻塞而且它有多个子进程,则在其一个子进程终止时,wait就立即返回。因为wait返回终止子进程的进程ID,所以它总能了解到哪一个子进程终止了】
2:waitpid提供了一个wait的非阻塞版本。
3:waitpid支持作业控制。