exit函数和_exit函数的区别

来源:互联网 发布:arttemplate.js 编辑:程序博客网 时间:2024/04/29 14:52

高级I/O函数

在Linux标准库中,有一套称为高级I/O函数,例如我们所熟知的printf,fopen,fread,fwrite都在此列,他们也被称为缓冲I/O。其特征是对应每一个打开的文件,都存在一个缓冲区,在每次读文件时会多读若干条记录,这样下次读文件时就可以直接从内存的缓冲区去读。在每次写文件时也会先写入缓冲区,当缓冲区写满,或者我们手动的刷新缓冲区,或者遇到\n,EOF这样的结束符,才会把对应的数据从缓冲区写入到文件中。这样的好处是大大增加的文件的读写的速度,因为我们都知道磁盘上的读写速度是很慢的,但这也为我们编程带来了一点麻烦,例如有些数据,我们认为已经写入了文件,但实际上它们很可能存在在缓冲区中。

关于printf的缓冲区问题推荐大家看下面的博客:
http://blog.csdn.net/bit_clearoff/article/details/53998476

exit和exit

首先我们来看看下面的实例:
这里写图片描述
从图片中我们可以看出,通过exit(0)来结束掉main函数的程序可以输出结果,通过调用_exit(0)函数的程序不能输出结果。

这时为什么呢????
我们来看看exit()和_exit()各组定义在哪个头文件中吧:
_exit定义在unistd.h中的第273行:
这里写图片描述

而exit()定义在stdlib.h文件中:
这里写图片描述
exit函数:定义在C标准库stdlib.h中;当我们调用exit(0)时,表示正常退出当前进程,当我们调用eixt(1)时表示非正常退出当前进程。
具体可以查看stdlib.h文件中的宏定义:

这里写图片描述

其中exit在结束进程之前要做以下的事情:

  1. 调用atexit()注册的函数(出口函数)

    atexit()函数定义在stdlib中,它的函数定义为:int atexit(void (*)(void)),形参为一个返回值为void,参数为void的函数指针,很多时候我们需要在程序退出的时候做一些诸如释放资源的操作,但程序退出的方式有很多种,比如main()函数运行结束、在程序的某个地方用exit()结束程序、用户通过Ctrl+C或Ctrl+break操作来终止程序等等,因此需要有一种与程序退出方式无关的方法来进行程序退出时的必要处理。方法就是用atexit()函数来注册程序正常终止时要被调用的函数。
    这里写图片描述
    在一个程序中最多可以用atexit()注册32个处理函数,这些处理函数的调用顺序与其注册的顺序相反,也即最先注册的最后调用,最后注册的最先调用。
    这里写图片描述
    我们可以使用atexit()函数在main函数结束时对整个进程的内存空间进行销毁,作用相当于C++中的析构函数.

  2. 调用cleanup()关闭所有的流

    这一步操作导致所有的缓冲被输出

  3. 最后调用_exit()函数终止进程

    _exit()函数主要做了清理内存空间,结束进程调用等工作。

    案例分析

    这下我们应该了解了出现前面例子中情况的原因了,是因为exit函数在结束进程时用cleanup()刷新了缓冲区,使缓冲区中的数据被输出,而_exit函数只是exit函数中的一部分,它调用了系统调用函数exit().

所以eixt和_exit函数我们可以用下面这张图来总结一下:
这里写图片描述

关于printf的缓冲区问题推荐大家看下面的博客:
http://blog.csdn.net/bit_clearoff/article/details/53998476

1 0
原创粉丝点击