#include <stdio.h>
#include <stdlib.h>
int main(void)
{
pid_t pid;
if((pid=fork())==-1)
{
printf("error");
}
else if(pid==0)
{
printf("ok");
exit(0);
}
else
{
printf("parent process,output begin ");
_exit(0);
}
}
以上代码编译后执行,可以看到只打印出ok,父进程的打印并没有出现。因为printf是带有缓冲的IO函数,执行printf时,输出写到了缓冲区但并未显示,而执行到exit()函数时,由于exit会清理缓存,所以缓冲写到标准输出。而_exit()不会清理缓存而直接退出,所以不会有输出产生。但是有时也产生输出时:当printf内有\n时,会清理缓存,此时的_exit()会输出。
在linux的标准库函数中,有一套称作高级I/O的函数,我们熟知的printf 、fopen 、fread 、fwrite都在此列,他们也被称作缓冲I/O。其特征是对应每一个打开的文件,都存在一个缓冲区, 在内存中都有一片缓冲区,每次读文件会多读若干条记录,这样下次读文件时就可以直接从内存的缓存中取出,每次写文件时也仅仅是写入到内存的缓冲区,等待满足一定的条件(达到一定的数量,或者遇到特定字符,如换行和文件结束符EOF),再将缓冲区的内容一次性的写入文件,这样就大大增加了文件读写的速度,但也为我们编程带来了一点点麻烦,如果有些数据,我们认为已经写入了文件,实际上因为没有满足特定的条件,他们还只是保存在缓冲区内,这时我们用_exit函数直接将程序关闭,缓冲区中的数据就会丢失,反之,如果向保证数据的完整性,就一定要使用exit函数。
exit()函数与_exit()函数最大的区别就在于exit()函数在调用exit系统调用之前要检查文件的打开情况,把文件缓冲区中的内容写回文件,就是图中的"清理I/O缓冲"一项。
exit()函数定义在stdlib.h中,而_exit()定义在unistd.h中。exit()和_exit()都用于正常终止一个函数。但_exit()直接是一个sys_exit系统调用,而exit()则通常是普通函数库中的一个函数。它会先执行一些清除操作,例如调用执行各终止处理函数、关闭所有标准IO等,然后调用sys_exit。