
当一个进程终止时,操作系统会进行如下操作:
进程的终止一般由三种情况触发:
return 0)。Segmentation Fault)。kill 命令)。main函数的返回值通常表明程序的执行情况,通过不同的返回值可以表明程序运行正常或者通过数字表明出错原因,这个返回值就是进程退出码。父进程要知道子进程的运行情况,所以退出码会存在于子进程的PCB中,即使代码和页表数据清除也可以得到子进程信息。
在 Linux 系统中,进程终止的常见方法包括以下几种:
正常终止指的是进程按照预期逻辑完成任务并退出,可以使用以下方式:
当 main() 函数执行 return n; 时,实际上等价于 exit(n);,操作系统会将 main() 返回的值作为进程的退出码,作为exit()的参数。
#include <stdio.h>
int main() {
printf("程序正常执行\n");
return 0; // 进程正常终止,返回码 0
}exit() 函数是 C 标准库提供的进程终止函数,它执行以下操作:
atexit() 注册的函数)。_exit() 终止进程。#include <stdio.h>
#include <stdlib.h>
int main() {
printf("使用 exit() 终止进程\n");
exit(0); // 进程正常终止,返回码 0
}_exit(n) 是 系统调用,它与 exit(n) 类似,但不会执行 atexit() 注册的清理函数,也不会刷新 stdio 缓冲区,而是直接终止进程。
#include <unistd.h>
int main() {
printf("使用 _exit() 终止进程\n");
_exit(0); // 立即终止进程
}exit() 和 _exit() 的主要区别:

函数 | 刷新缓冲区 | 关闭文件描述符 | 调用 atexit() 注册的函数 |
|---|---|---|---|
exit() | 是 | 是 | 是 |
_exit() | 否 | 是 | 否 |
进程也可能因 运行时错误 或 外部干预 导致异常终止,主要有以下几种情况:
操作系统可以通过 信号(signal) 终止进程,例如:
kill -9 <PID> 发送 SIGKILL 强制杀死进程。Ctrl + C 发送 SIGINT 终止前台进程。#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
void sigint_handler(int signum) {
printf("收到 SIGINT 信号,进程终止\n");
exit(1);
}
int main() {
signal(SIGINT, sigint_handler); // 捕获 SIGINT 信号
while (1); // 无限循环,等待信号
}当用户按 Ctrl + C,进程会被 SIGINT 终止,并输出 "收到 SIGINT 信号,进程终止"。
如果进程访问了 非法地址,操作系统会发送 SIGSEGV 信号,导致进程异常终止。
int main() {
int *ptr = NULL;
*ptr = 10; // 访问非法地址,进程终止
}进程退出码(Exit Code)用于表示进程的 终止状态,可通过 $? 获取最近终止进程的退出码。例如:
./my_program
echo $? # 输出进程退出码退出码 | 含义 |
|---|---|
0 | 进程成功执行 |
1 | 一般错误(错误但未具体说明) |
2 | 误用 shell 命令(非法参数等) |
126 | 权限问题,无法执行命令 |
127 | 命令未找到 |
128+n | 进程因信号 n 终止,例如 SIGKILL (9) -> 137 |
130 | Ctrl + C 终止进程(SIGINT) |
255 | 超出正常范围,通常是 exit(-1) 或 exit(256) |
示例:
ls /root
echo $? # 若无权限访问,返回 126进程终止是计算机程序运行的 最终阶段,理解它的机制有助于更好地进行 进程控制 和 调试。我们可以使用 return、exit()、_exit() 进行 正常终止,也可能因信号、非法操作等导致 异常终止。此外,进程退出码是 进程状态的反馈,在 Linux Shell 和 C 语言编程中都非常重要。