exit()函数
函数原型
#include <stdlib.h>
void exit(int status);
参数:
status: 用于表示进程的终止状态。通常情况下,0表示正常退出,非零值表示异常退出。
宏:
EXIT_SUCCESS 表示正常退出 表示正常退出的状态码,其值通常为 0
EXIT_FAILURE 表示异常退出的状态码,其值通常为非零
返回值:
函数没有返回值,它会直接终止当前进程的执行。
函数用法
exit()
函数用于终止当前进程的执行,并返回状态码给其父进程。通常在子进程中调用 exit()
来结束进程的执行。
wait()函数
函数原型
#include <sys/types.h>
#include <sys/wait.h>
pid_t wait(int *status);
参数:
status: 一个整型指针,用于存储子进程的终止状态。
宏:
WIFEXITED(status): 判断子进程是否正常退出的宏。
WEXITSTATUS(status): 获取子进程正常退出时的状态码。
WIFSIGNALED(status): 判断子进程是否因信号而终止的宏。
WTERMSIG(status): 获取导致子进程终止的信号编号。
返回值:
成功时返回结束的子进程的 PID。
失败时返回 -1,并设置 errno。
宏值:
WIFEXITED(status)
正常终止: 返回一个非零值(true),表示子进程是通过调用 exit() 正常终止。
异常终止: 返回 0(false),表示子进程不是正常终止的,可能是通过调用 abort() 函数终止,或者收到了一个信号而终止。
WEXITSTATUS(status)
正常终止: 返回值为真,WEXITSTATUS(status) 用于获取子进程的退出状态码。
如果子进程是通过调用 exit(status) 正常终止的,那么 WEXITSTATUS(status) 返回的就是 exit(status) 中 status 参数的值。否则,WEXITSTATUS(status) 的行为是未定义的。
WIFSIGNALED(status)
通过信号终止: 返回一个非零值(true),表示子进程是通过一个未捕获的信号终止的,即子进程收到了一个信号,但没有被处理。
不是因信号而终止: 返回 0(false),表示子进程不是因信号而终止的,可能是通过正常的 exit() 调用终止。
WTERMSIG(status)
当 WIFSIGNALED(status) 返回真时,WTERMSIG(status) 用于获取导致子进程终止的信号编号。
如果子进程是因为接收到信号而终止的,则 WTERMSIG(status) 返回的是该信号的编号。
函数用法
wait()
函数用于父进程等待子进程的终止,并获取子进程的终止状态。
演示代码
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
int main() {
printf("主进程 pid = %d\n", getpid());
pid_t child_pid = fork(); // 创建子进程
if (child_pid == -1)
{
perror("fork");
return EXIT_FAILURE;
}
else if (child_pid == 0)
{
// 子进程
printf("第一个子进程 pid = %d\n", getpid());
pid_t child_child_pid = fork(); // 创建孙进程
if (child_child_pid == -1)
{
perror("fork");
return EXIT_FAILURE;
}
else if (child_child_pid == 0)
{
// 孙进程
printf("孙进程 pid = %d\n", getpid());
printf("孙进程的异常结束\n");
exit(EXIT_FAILURE);
} else {
// 子进程等待孙进程结束
int status;
pid_t wpid = wait(&status);
printf("子进程--父进程 获取孙进程 pid = %d\n", wpid);
if (WIFEXITED(status))
{
printf("孙进程异常退出,退出码为:%d\n", WEXITSTATUS(status));
}
if (WIFSIGNALED(status))
{
printf("孙进程因信号而终止\n");
// 进一步测试 WIFSIGNALED 宏
if (WIFSIGNALED(status))
{
printf("孙进程的信号编号为:%d\n", WTERMSIG(status));
}
}
// ……
}
printf("子进程正常退出\n");
exit(EXIT_SUCCESS);
} else {
// 等待子进程结束
int status;
pid_t wpid = wait(&status);
printf("主进程--父进程 获取子进程 pid = %d\n", wpid);
if (WIFEXITED(status)) {
printf("子进程正常退出,退出码为:%d\n", WEXITSTATUS(status));
} else if (WIFSIGNALED(status)) {
printf("子进程因信号而终止\n");
}
// 进一步测试 WIFSIGNALED 宏
if (WIFSIGNALED(status)) {
printf("子进程的信号编号为:%d\n", WTERMSIG(status));
}
}
return 0;
}