exit() 和 wait() 函数的用法

本文详细介绍了C语言中的exit()函数用于终止进程及其返回状态码给父进程,以及wait()函数用于父进程等待子进程终止并获取状态。通过示例展示了如何使用这些函数进行进程管理和异常处理。
摘要由CSDN通过智能技术生成

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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值