面试题答案
一键面试进程正常退出和异常退出时系统资源回收情况的不同
- 正常退出(以调用exit函数为例)
- 系统会按照一定的顺序清理进程占用的资源。首先,会执行所有已注册的终止处理函数(通过
atexit
函数注册的函数),这些函数可以用于执行一些程序结束前的清理工作,比如关闭打开的文件、释放动态分配的内存等。 - 然后,会刷新所有标准I/O流(如
stdout
、stderr
等)的缓冲区,确保缓冲区中的数据被正确输出到对应的设备或文件中。 - 最后,操作系统内核会回收进程占用的内核资源,如进程控制块(PCB),以及与进程相关的内存空间等。
- 系统会按照一定的顺序清理进程占用的资源。首先,会执行所有已注册的终止处理函数(通过
- 异常退出(如程序崩溃)
- 对于异常退出,系统通常不会执行通过
atexit
注册的终止处理函数,也不会主动刷新标准I/O流缓冲区。这可能导致缓冲区中的数据丢失,特别是在缓冲区未填满时程序崩溃的情况。 - 操作系统内核同样会回收进程占用的内核资源,如进程控制块和内存空间等。但与正常退出不同的是,异常退出可能是由于程序访问非法内存、除零等错误导致的,这些错误可能会在进程退出前对系统产生一些不良影响,如损坏共享内存区域等。
- 对于异常退出,系统通常不会执行通过
代码层面体现两种退出方式
- 正常退出(使用exit函数)
#include <stdio.h>
#include <stdlib.h>
void cleanup() {
printf("Cleaning up...\n");
}
int main() {
atexit(cleanup);
printf("Program is about to exit normally.\n");
exit(0);
return 0;
}
在上述代码中,通过atexit
函数注册了cleanup
函数,当调用exit(0)
时,cleanup
函数会先被执行,然后程序正常退出。
2. 异常退出(以除零错误为例模拟程序崩溃)
#include <stdio.h>
int main() {
int a = 10;
int b = 0;
printf("Program is about to cause an exception.\n");
int result = a / b; // 这里会导致除零错误,程序异常退出
printf("This line will not be printed.\n");
return 0;
}
在这段代码中,由于b
为0,执行a / b
时会引发除零错误,程序异常退出,不会执行注册的终止处理函数(如果有),也不会刷新标准I/O流缓冲区(如果缓冲区中有未输出的数据)。