waitpid()
是一个系统调用函数,用于等待指定的子进程结束或收到特定的信号。它在许多操作系统(如UNIX和Linux)中可用。
waitpid()
函数的原型如下:
#include <sys/types.h>
#include <sys/wait.h>
pid_t waitpid(pid_t pid, int *status, int options);
函数waitpid()
用于等待指定的子进程结束,并获取其状态信息。它的返回值可以提供有关子进程的一些信息,包括进程的退出状态和退出原因。返回值的含义如下:
-
如果
waitpid()
返回-1,表示出现错误,无法等待子进程结束。此时,可以通过errno
变量获取具体的错误信息。 -
如果
waitpid()
返回0,表示指定的子进程仍在运行,尚未结束。 -
如果
waitpid()
返回正整数,表示成功等待到了一个子进程的结束。返回值是结束子进程的进程ID。
此外,可以通过一些宏来进一步解析返回值,以获取有关子进程退出状态的信息。例如:
-
WIFEXITED(status)
:如果子进程正常终止(通过调用exit()
或返回main()
),则该宏返回真。 -
WEXITSTATUS(status)
:如果WIFEXITED(status)
为真,则该宏提取子进程的退出状态。 -
WIFSIGNALED(status)
:如果子进程是因为未捕获的信号而终止的(例如通过调用abort()
或接收到SIGKILL
信号),则该宏返回真。 -
WTERMSIG(status)
:如果WIFSIGNALED(status)
为真,则该宏提取导致子进程终止的信号编号。
该函数接受三个参数:
1.pid
:指定要等待的子进程的进程ID。可以使用以下值:
> 0
:等待具有指定进程ID的子进程。-1
:等待任何子进程,类似于wait()
。0
:等待与调用进程属于同一进程组的任何子进程。< -1
:等待进程组ID等于给定值的任何子进程。
2.status
:一个指向整数的指针,用于存储子进程的退出状态信息。可以为NULL
,表示不关心退出状态。
3.options
:用于指定附加选项的整数值。常用的选项包括:
WNOHANG
:如果没有任何子进程结束,则立即返回,而不阻塞等待。
WNOHANG
是waitpid()
函数的一个选项参数,用于在调用waitpid()
时指定非阻塞模式。
通常情况下,当调用waitpid()
函数时,如果没有子进程结束,父进程会被阻塞(挂起)等待子进程结束,并且只有在子进程结束后才会继续执行父进程的代码。这种情况下,父进程会一直等待直到有子进程结束,才能继续向下执行。
而当使用WNOHANG
选项时,waitpid()
函数将以非阻塞模式运行。如果没有子进程已经结束,它不会挂起父进程,而是立即返回0,父进程可以继续执行其他操作。这样父进程可以通过轮询waitpid()
函数来检查子进程的状态,而不必被阻塞等待。
使用WNOHANG
选项可以在父进程中实现非阻塞的子进程回收,提供更灵活的进程管理方式。父进程可以继续执行其他任务,而在需要时检查子进程的状态,并及时回收僵尸进程。
WUNTRACED
:也等待已停止的子进程。
WUNTRACED
是waitpid()
函数的一个选项参数,用于在调用waitpid()
时指定对已暂停的子进程也进行处理。
当一个子进程被暂停(例如,收到SIGSTOP
信号),它进入了被称为暂停(stopped)状态。在这种情况下,如果父进程调用waitpid()
等待子进程结束,通常只会等待子进程终止(退出)或被终止(收到终止信号)。而被暂停的子进程可能不会被等待,而是被忽略。
使用WUNTRACED
选项时,waitpid()
函数将对已暂停的子进程进行处理。如果子进程当前处于暂停状态,waitpid()
会返回其进程ID,并提供相应的状态信息。这使得父进程可以检查和处理暂停的子进程的状态。
通常,使用WUNTRACED
选项与使用WIFSTOPPED()
和WSTOPSIG()
宏一起使用,以判断子进程是否处于暂停状态,以及由哪个信号导致的暂停。
总结起来,使用WUNTRACED
选项可以让waitpid()
函数在等待子进程结束时,同时处理已暂停的子进程。这样父进程可以及时检查和处理暂停状态的子进程,从而实现更全面的进程管理。
WCONTINUED
:也等待已继续执行的子进程。
简单来说WCONTINUED是阻塞的
WCONTINUED
是waitpid()
函数的一个选项参数,用于在调用waitpid()
时指定对已继续执行的子进程也进行处理。
当一个子进程被暂停后又被继续执行(例如,收到SIGCONT
信号),它进入了继续执行(continued)状态。在这种情况下,如果父进程调用waitpid()
等待子进程结束,通常只会等待子进程终止(退出)或被终止(收到终止信号)。被继续执行的子进程可能不会被等待,而是被忽略。
使用WCONTINUED
选项时,waitpid()
函数将对已继续执行的子进程进行处理。如果子进程当前处于继续执行状态,waitpid()
会返回其进程ID,并提供相应的状态信息。这使得父进程可以检查和处理继续执行的子进程的状态。
通常,使用WCONTINUED
选项与使用WIFCONTINUED()
宏一起使用,以判断子进程是否处于继续执行状态。
总结起来,使用WCONTINUED
选项可以让waitpid()
函数在等待子进程结束时,同时处理已继续执行的子进程。这样父进程可以及时检查和处理继续执行状态的子进程,从而实现更全面的进程管理。
waitpid()
函数的返回值是子进程的进程ID,或者在出错时返回-1。根据返回值和status
的值,可以判断子进程的退出状态。
下面是一个简单的示例代码,演示了如何使用waitpid()
函数等待子进程的结束:
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
int main() {
pid_t pid;
int status;
pid = fork();
if (pid == 0) {
// 子进程
printf("Child process\n");
sleep(2);
return 42;
} else if (pid > 0) {
// 父进程
printf("Parent process\n");
waitpid(pid, &status, 0);
if (WIFEXITED(status)) {
printf("Child exited with status: %d\n", WEXITSTATUS(status));
}
} else {
// fork()失败
perror("fork() error");
return 1;
}
return 0;
}