函数描述 :等待进程改变状态,它会暂停当前进程的执行,直到有一个子进程结束。当子进程结束时,wait函数会返回该子进程的进程ID,并将子进程的退出状态存储在status指向的整数变量中。
wait—— wait for process to change state
参数:一级指针
原型:pid_t wait(int *status);
参数status用来保存被收集进程退出时的一些状态,它是一个指向int类型的指针。但如果我们对这个子进程是如何结束毫不在意,只想把这个僵尸进程消灭掉,(事实上绝大多数情况下,我们都会这样想),我们就可以设定这个参数为NULL,就像下面这样:
pid = wait(NULL);
所有这些系统调用都用于等待调用进程的子进程的状态更改,并获取状态已更改的子进程的信息。状态变化被认为是:子进程终止;子进程被一个信号拦住了;或子进程被一个信号唤醒了。对于结束的子进程,执行wait允许系统释放与子进程相关的资源;如果不执行wait,则终止的子进程保持在“僵尸”①状态。
如果子进程已经改变了状态,那么这些调用将立即返回。否则,它们会阻塞,直到其中任何一个子进程改变状态或信号处理程序中断调用。
解析①:当父进程忘了用wait()函数等待已终止的子进程时,子进程就会进入一种无父进程的状态,此时子进程就是僵尸进程.
下面是一个示例代码,演示了wait函数的使用:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
pid_t pid = fork();
if(pid < 0)
{
perror("fork error ");
return -1;
}
else if(pid == 0)
{
sleep(4);
printf("child = %d parent = %d ",getpid(),getppid());
}
else if(pid > 0 )
{
pid = wait( NULL );// 无论子进程运行多久(子进程状态一改变)最终都会回到父进程一起退出
printf("parent = %d ",getpid());
}
return 0;
}
wait函数和waitpid函数都是用于等待子进程结束的函数。
waitpid函数的原型为:
pid_t waitpid(pid_t pid, int *status, int options);
它允许指定对哪个子进程进行等待。参数pid指定要等待的子进程的进程ID,如果pid为正数,则表示等待具有该进程ID的子进程;如果pid为-1,则表示等待任意子进程;如果pid为0,则表示等待与调用进程属于同一个进程组的任意子进程;如果pid为负数,则表示等待进程组ID等于pid绝对值的任意子进程。
status参数与wait函数的作用相同,用于存储子进程的退出状态。options参数可以指定一些额外的选项,如WNOHANG表示非阻塞地等待子进程结束。
使用wait函数或waitpid函数可以实现进程间的同步,父进程可以利用这两个函数等待子进程的结束,并获取子进程的退出状态。这样可以确保父进程在子进程完成后再继续执行后续的操作。
下面是一个示例代码,演示了waitpid函数的使用:
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
int main() {
pid_t pid = fork();
if (pid == 0) {
// 子进程执行的代码
printf("Child process ");
sleep(3);
printf("Child process finished ");
return 0;
} else if (pid > 0) {
// 父进程执行的代码
printf("Parent process ");
int status;
waitpid(pid, &status, 0);
printf("Child process exited with status %d ", status);
} else {
// fork失败
printf("Fork failed ");
return 1;
}
return 0;
}
在上面的代码中,父进程调用fork函数创建子进程,然后通过waitpid函数等待子进程的结束,并获取子进程的退出状态。子进程会先打印一条消息,然后休眠3秒钟,最后返回0表示正常退出。父进程会在子进程结束后打印子进程的退出状态。
注意,wait和waitpid函数在等待子进程结束时会阻塞当前进程,直到有子进程结束。如果不希望阻塞,可以使用waitpid的WNOHANG选项,或者利用信号机制来处理子进程的结束事件。