一、wait函数
- 作用:wait函数用于使父进程等待它的一个子进程结束。当调用wait函数时,父进程会被阻塞,直到它的一个子进程结束为止。这个函数常用于防止子进程变成僵尸进程,即子进程已经结束但其父进程还没有获取其终止状态。
- 参数:wait函数接受一个指向整型的指针作为参数,该指针用于保存被收集的子进程退出时的一些状态信息。如果这个状态信息对父进程不重要,可以将该参数设置为NULL。
- 返回值:如果成功,wait会返回被收集的子进程的进程ID。如果调用进程没有子进程,调用会失败,此时wait返回-1,并设置errno为ECHILD。
二、waitpid函数
-
作用:waitpid函数与wait函数类似,也是用于父进程等待子进程的结束。不过,waitpid函数提供了更多的灵活性,允许父进程等待指定的子进程,并且可以选择是否以阻塞方式等待。
-
参数:
- pid:此参数用于指定要等待的子进程的进程ID。它可以有以下几种取值:
- pid>0:等待进程ID等于pid的子进程。
- pid=-1:等待任意子进程,此时waitpid与wait功能相同。
- pid=0:等待和当前调用waitpid函数的进程同一个进程组的所有子进程。
- pid<-1:等待指定进程组内的任意子进程,其中pid的绝对值表示进程组的ID。
- status:与wait函数的status参数类似,用于保存子进程的退出状态。如果不关心退出状态,可以设为NULL。
- options:用于控制waitpid的行为,例如是否阻塞等待。常用的选项有WNOHANG(非阻塞模式)等。
- pid:此参数用于指定要等待的子进程的进程ID。它可以有以下几种取值:
-
返回值:
- 如果成功,则返回被等待的子进程的进程ID。
- 如果设置了WNOHANG选项且没有子进程结束,或者指定的子进程尚未结束,则返回0。
- 如果调用进程没有子进程,或者出现其他错误,则返回-1,并设置errno来表示错误原因。
总结:
- wait和waitpid函数都用于父进程等待子进程的结束,以回收子进程资源并防止僵尸进程的产生。
- wait函数是阻塞式的,只能等待任意一个子进程结束;而waitpid函数提供了更多的选项和灵活性,可以指定等待的子进程、是否阻塞等。
- 这两个函数的返回值都与被等待的子进程的进程ID相关,如果成功则返回子进程的进程ID;如果失败或没有子进程可等待,则返回-1或其他特殊值。
-
#include <stdio.h> #include <sys/types.h> #include <unistd.h> #include <sys/wait.h> waitpid非阻塞回收子进程的退出资源 int main(int argc, const char *argv[]) { //定义局部变量 int a = 0; //使用fork来创建一个子进程 pid_t pid = fork(); if(pid < 0) { perror("fork child process error"); return -1; } else if(0 == pid) { //子进程在执行代码 while(1) { a++; printf("子进程:a = %d\n",a); printf("I am child process!\n"); sleep(1); } } else { //使用wait阻塞回收子进程的退出资源 printf("等待回收子进程中......\n"); pid_t exitPID = wait(NULL);//阻塞 printf("exitPID = %d的子进程已被回收!\n", exitPID); //父进程在执行代码 while(1) { a++; printf("父进程:a = %d\n",a); printf("I am parent process!\n"); sleep(1); } } printf("test!!!\n"); return 0; }