父进程等待多个子进程时可以使用 wait()
函数,但有一些要点需要注意,下面为你详细介绍相关内容。
可以使用 wait()
函数等待多个子进程的原理
wait()
函数会让调用它的父进程暂停执行,直到它的某个子进程结束,然后返回结束子进程的进程ID,并将子进程的终止状态信息存储在 wstatus
参数指向的位置。要等待多个子进程,父进程可以循环调用 wait()
函数,每调用一次就等待一个子进程结束,直至所有子进程都结束。
示例代码
以下示例展示了如何使用 wait()
函数让父进程等待多个子进程结束:
c
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#define NUM_CHILDREN 3
int main() {
pid_t pid;
int i, status;
// 创建多个子进程
for (i = 0; i < NUM_CHILDREN; i++) {
pid = fork();
if (pid < 0) {
perror("fork");
exit(EXIT_FAILURE);
} else if (pid == 0) {
// 子进程代码
printf("子进程 %d 开始执行,进程ID: %d\n", i + 1, getpid());
sleep(1 + i); // 模拟不同的执行时间
printf("子进程 %d 执行完毕\n", i + 1);
exit(i + 1);
}
}
// 父进程等待所有子进程结束
for (i = 0; i < NUM_CHILDREN; i++) {
pid = wait(&status);
if (pid == -1) {
perror("wait");
exit(EXIT_FAILURE);
}
if (WIFEXITED(status)) {
printf("子进程 %d 已结束,退出状态码: %d\n", pid, WEXITSTATUS(status));
}
}
return 0;
}
代码解释
- 创建多个子进程 :通过
for
循环调用fork()
函数创建多个子进程。每个子进程会执行一些任务(这里用sleep
函数模拟不同的执行时间),然后调用exit()
函数退出,并设置自己的退出状态码。 - 父进程等待子进程 :父进程通过另一个
for
循环多次调用wait()
函数,每次调用都会等待一个子进程结束。当wait()
函数返回时,会输出结束子进程的进程ID和退出状态码。
使用 wait()
函数等待多个子进程的局限性
- 顺序问题 :
wait()
函数并不区分具体等待哪个子进程结束,它只是等待任意一个子进程结束。这意味着父进程无法按照特定的顺序等待子进程结束。 - 错误处理较复杂:如果在等待过程中某个子进程因为信号中断等原因异常结束,需要仔细处理错误情况,确保所有子进程的资源都能被正确回收。
替代方案
可以考虑使用 waitpid()
函数,它能让父进程指定等待某个特定的子进程结束,或者按照一定的条件等待子进程结束,使用起来更加灵活。