问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

[操作系统] 进程终止

创作时间:
作者:
@小白创作中心

[操作系统] 进程终止

引用
CSDN
1.
https://blog.csdn.net/SDFsoul/article/details/145458436

在计算机操作系统中,进程(Process)是程序在运行中的实例,而进程的生命周期始于创建,终于终止。进程终止不仅仅意味着程序执行结束,还涉及资源的回收、状态的传递、以及可能的错误处理。在 Linux 和 Unix 系统中,进程的终止有多种方式,包括正常终止、异常终止、信号终止等。本文将深入探讨进程终止的概念、方法以及相关的进程退出码。

进程终止的基本概念

当一个进程终止时,操作系统会进行如下操作:

  • 释放进程所占用的资源(内存、文件描述符、CPU 等)。
  • 通知父进程(如果有的话),让其可以回收进程的退出状态。
  • 从进程调度器中移除该进程,使其不再执行。

进程的终止一般由三种情况触发:

  1. 代码运行完成,正常终止(例如
    return 0
    )。
  2. 代码运行异常,导致非正常终止(例如
    Segmentation Fault
    )。
  3. 外部干预,如用户手动终止或系统强制终止(例如
    kill
    命令)。

main
函数的返回值通常表明程序的执行情况,通过不同的返回值可以表明程序运行正常或者通过数字表明出错原因,这个返回值就是进程退出码。父进程要知道子进程的运行情况,所以退出码会存在于子进程的PCB中,即使代码和页表数据清除也可以得到子进程信息。

进程终止的常见方法

在 Linux 系统中,进程终止的常见方法包括以下几种:

正常终止

正常终止指的是进程按照预期逻辑完成任务并退出,可以使用以下方式:

return 语句


main()
函数执行
return n;
时,实际上等价于
exit(n);
,操作系统会将
main()
返回的值作为进程的退出码,作为
exit()
的参数。


#include <stdio.h>
int main() {
    printf("程序正常执行\n");
    return 0;  // 进程正常终止,返回码 0
}

exit(n)

exit()
函数是 C 标准库提供的进程终止函数,它执行以下操作:

  • 执行用户定义的清理函数
    atexit()
    注册的函数)。
  • 关闭所有打开的文件流,刷新缓冲区。
  • 调用
    _exit()
    终止进程。

#include <stdio.h>
#include <stdlib.h>
int main() {
    printf("使用 exit() 终止进程\n");
    exit(0);  // 进程正常终止,返回码 0
}

_exit(n)

_exit(n)
系统调用,它与
exit(n)
类似,但不会执行
atexit()
注册的清理函数,也不会刷新
stdio
缓冲区,而是直接终止进程。


#include <unistd.h>
int main() {
    printf("使用 _exit() 终止进程\n");
    _exit(0);  // 立即终止进程
}

exit()

_exit()
的主要区别:

函数
刷新缓冲区
关闭文件描述符
调用atexit()注册的函数
exit()
_exit()

异常终止

进程也可能因运行时错误外部干预导致异常终止,主要有以下几种情况:

1) 信号终止

操作系统可以通过信号(signal)终止进程,例如:

  • kill -9
    发送
    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 信号,进程终止"

2) 访问非法内存

如果进程访问了非法地址,操作系统会发送
SIGSEGV
信号,导致进程异常终止。


int main() {
    int *ptr = NULL;
    *ptr = 10;  // 访问非法地址,进程终止
}

进程退出码(Exit Code)解析

进程退出码(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 语言编程中都非常重要。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号