Linux_进程退出与进程等待

一、进程退出

退出场景

  • 正常终止 ‌:代码执行完毕且结果符合预期(退出码为 0)。
  • 异常终止 ‌:运行结果错误(退出码非 0)或进程被信号强制终止。(如 SIGINTSIGSEGV)。

退出方法

  • 正常退出方式 ‌:
    • return:从 main 函数返回,隐含调用 exit 函数。
    • exit(int status):标准库函数,执行清理操作(如刷新缓冲区、调用 atexit 注册的函数)后终止进程。
    • _exit(int status):系统调用,直接终止进程,不刷新缓冲区。

exit函数和_exit函数的区别

_exit :立即终止进程,不执行任何清理操作

exit : 调用清理函数、刷新缓冲区后终止进程

二、进程等待‌

为什么要有进程等待?

父进程在忙,子进程结束了,但无人回收,这样就造成了"死亡"的子进程一直占用资源

这个时候的子进程被称为"僵尸进程"

为了解决这个问题,最初的思路是:让父进程停下,等待子进程执行完,然后回

    • 回收资源 ‌:子进程退出后若未回收,将残留 task_struct 结构(僵尸进程)。
    • 获取状态‌:父进程需通过等待机制获取子进程的退出码或异常信号。

1、wait 函数参数解析

复制代码
pid_t wait(int *status);  

参数说明

  • ‌**status** ‌:
    • 类型为 int*,是输出型参数,用于接收子进程的终止状态(如退出码或终止信号)。
    • 若不关心子进程状态,可设为 NULL(如 wait(NULL)

返回值

  • 成功时返回终止的子进程 pid;
  • 无子进程或调用失败时返回

2、waitpid 函数参数详解

复制代码
pid_t waitpid(pid_t pid, int *status, int options); 
  1. 参数说明
    • ‌**pid** ‌:
      • ‌**> 0**‌:等待指定 pid 的子进程;
      • ‌**-1** ‌:等待任意子进程(等价于 wait);
      • ‌**0**‌:等待与调用进程同进程组的所有子进程;
      • ‌**< -1** ‌:等待进程组 ID 为 |pid| 的任意子进程。
    • ‌**status** ‌:
      • waitstatus 参数,存储子进程终止状态。
    • ‌**options** ‌:
      • ‌**0**‌:默认阻塞模式;
      • ‌**WNOHANG** ‌:非阻塞模式,若指定子进程未结束则立即返回 0
      • ‌**WUNTRACED**‌:支持作业控制,返回已暂停的子进程状态。
  2. 返回值
    • 成功时返回子进程 pid;
    • 若使用 WNOHANG 且无子进程终止,返回 0
    • 错误时返回 -1

waitpid 函数第二个参数详解

waitpid 函数的第二个参数 int *status 是用于接收子进程终止状态的关键参数,需配合特定宏解析具体信息。以下是详细说明:

tatus不能简单的当作整型来看,要从二进制的角度来看,32位下,整型转化为二进制有32个bit位,但是我们仅关注低16位

正常退出 ‌(子进程调用 exit_exit):

复制代码
if (WIFEXITED(status)) {  
    int exit_code = WEXITSTATUS(status);  // 提取低8位退出码(取值范围0~255):ml-citation{ref="2,4" data="citationList"}  
}  

信号终止‌(子进程被信号杀死):

复制代码
if (WIFSIGNALED(status)) {  
    int signal_num = WTERMSIG(status);    // 提取终止信号编号(如 SIGKILL=9):ml-citation{ref="4,7" data="citationList"}  
    printf("Terminated by signal: %d\n", signal_num);  
}  

暂停状态 ‌(需配合 WUNTRACED 选项):

复制代码
if (WIFSTOPPED(status)) {  
    int stop_signal = WSTOPSIG(status);   // 提取暂停信号编号(如 SIGSTOP=19):ml-citation{ref="4,7" data="citationList"}  
}  

status 的二进制位分布:

  • WIFEXITED(status):判断子进程是否正常退出(返回非零值时表示正常退出)。
  • WEXITSTATUS(status):若子进程正常退出,通过此宏获取子进程的退出码(如 exit(5) 中的 5)。
  • WIFSIGNALED(status):判断子进程是否因信号终止(返回非零值时表示被信号终止)。
  • WTERMSIG(status):若子进程因信号终止,通过此宏获取信号代码(如 SIGKILL 对应 9

可忽略性

若父进程不关心子进程状态,可将参数设为 NULL,此时仅等待子进程结束而不获取状态信息

关键细节

  • 指针的必要性 ‌:必须传递地址(如 &status),操作系统需要写入状态值到该地址。
  • 状态位结构 ‌:status 的整数值包含多个信息位,需通过宏函数按需提取。
  • wait 的关系 ‌:wait(&status) 等价于 waitpid(-1, &status, 0),二者的 status 解析方式一致

相关推荐
kunge20132 分钟前
Ubuntu22.04 安装virtualbox7.1
linux·virtualbox
清溪5493 分钟前
DVWA中级
linux
m0_7482540913 分钟前
2025最新华为云国际版注册图文流程-不用绑定海外信用卡注册
服务器·数据库·华为云
MUY099021 分钟前
应用控制技术、内容审计技术、AAA服务器技术
运维·服务器
楠奕25 分钟前
elasticsearch8.12.0安装分词
运维·jenkins
Sadsvit1 小时前
源码编译安装LAMP架构并部署WordPress(CentOS 7)
linux·运维·服务器·架构·centos
xiaok1 小时前
为什么 lsof 显示多个 nginx 都在 “使用 443”?
linux
java资料站1 小时前
Jenkins
运维·jenkins
苦学编程的谢2 小时前
Linux
linux·运维·服务器
G_H_S_3_2 小时前
【网络运维】Linux 文本处理利器:sed 命令
linux·运维·网络·操作文本