exit 和_exit 的区别

exit和_exit
作为系统调用而言,_exit和exit是一对孪生兄弟。
这时随便一个懂得C语言并且头脑清醒的人都会说,_exit和exit没有任何区别,但我们还要讲一下这两者之间的区别,这种区别主要体现在它们在函数库中
的定义。_exit在Linux函数库中的原型是:
#include
    void _exit(int status);
exit比较一下,exit()函数定义在 stdlib.h中,而_exit()定义在unistd.h中,从名字上看,stdlib.h似乎比unistd.h高级一点,那么,它们之间到底有什么区别呢?
     _exit()函数的作用最为简单:直接使进程停止运行,清除其使用的内存空间,并销毁其在内核中的各种数据结构;exit()函数则在这些基础上作了一些包装,在执行退出之前加了若干道工序,也是因为这个原因,有些人认为exit已经不能算是纯粹的系统调用。
      exit()函数与_exit()函数最大的区别就在于exit()函数在调用exit系统调用之前要检查文件的打开情况,把文件缓冲区中的内容写回文件,就是“清理I/O缓冲”。
在Linux 的标准函数库中,有一套称作“高级I/O”的函数,我们熟知的printf()、fopen()、fread()、fwrite()都在此列,它们也被称作“缓冲I/O(buffered I/O)”,其特征是对应每一个打开的文件,在内存中都有一片缓冲区,每次读文件时,会多读出若干条记录,这样下次读文件时就可以直接从内存的缓冲区中读取,每次写文件的时候,也仅仅是写入内存中的缓冲区,等满足了一定的条件(达到一定数量,或遇到特定字符,如换行符\n和文件结束符EOF),再将缓冲区中的内容一次性写入文件,这样就大大增加了文件读写的速度,但也为我们编程带来了一点点麻烦。如果有一些数据,我们认为已经写入了文件,实际上因为没有满足特定的条件,它们还只是保存在缓冲区内,这时我们用_exit()函数直接将进程关闭,缓冲区中的数据就会丢失,反之,如果想保证数据的完整性,就一定要使用exit()函数。


当我们用atexit(进程终止处理函数)时,用exit函数和_exit退出时会有不同效果,_exit调用时会破坏存储在栈中atexit函数储存的函数。
例:#include
#include
#include


void func1(void)
{
printf("func1\n");
}


void func2(void)
{
printf("func2\n");
}




int main(void)
{
printf("hello world.\n");

// 当进程被正常终止时,系统会自动调用这里注册的func1执行
atexit(func2);
atexit(func1);

printf("test\n");


return 0;       //正常
//exit(0);     //正常
//_exit(0);  //不正常




分别调用 return  exit 和 _exit 后的返回结果
return :  test
              func1
              func2
              
 exit:      test
              func1
              func2
              
_exit:     test                   

你可能感兴趣的:(Linux)