exit函数和_exit函数的二三事


我们知道做什么事情都是有始有终,在编程中也是一样。在Linux中创建一个进程后,程序的末尾我们要将其退出,在Linux中进程退出总共有八种方法,本篇文章主要讲解其中两个函数。


调用格式

#include<stdio.h>
#include<unistd.h>
void exit(int status);
void _exit(int status);

exit系列函数并没有返回值,它使用一个叫做终止状态的整型变量作为参数,内核会对这个终止状态进行检查,异常终止时,内核会直接产生一个终止状态字,描述异常终止的原因。对于终止状态字,我们可以调用wait或者waitpid函数来获取,有兴趣的小伙伴可以翻阅相关资料。
调用过程
这里写图片描述
调用过程如图所示,从图中可以看出:

  • _exit函数直接使进程停止,清除其使用的内存空间,和内核中的各种数据结构
  • exit函数在_exit的基础上进行了包装,加了好几道工序。

差别
exit函数在调用之前要检查文件的打开情况,在这个过程中会把缓冲区中的数据写入文件。_exit函数做事就比较果断,直接使进程终结。


这里讲点题外话:缓冲I/O
在Linux标准库中有中叫做缓冲I/O的操作,它的作用就是对应每一个打开的文件,都会在内存中存在一个缓冲区。每次读文件时,会读出若干条记录,方便下次读取。写文件也是同样的情况,先写到缓冲区,然后等满足一定条件,再将缓冲区中的数据写入文件。这种技术提高了文件读写的速度,但是也带来一些弊端。有时候你认为程序已经将数据写入文件,其实不然,所以有可能造成数据丢失。为了避免这种情况的发生,对于退出函数的理解就很重要了。


先看一段代码

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/types.h>
int main (int argc,char * argv[])
{
    pid_t pid;
    pid = fork();
    if(pid < 0)
    {
        printf("进程创建失败\n");
        return 0;
    }
    else if(pid == 0)
    {
        printf("子进程\n");
        printf("程序员真帅");
        exit(0);
    }
    else
    {
        sleep(3);
        printf("父进程\n");
        printf("程序员真棒");
        _exit(0);
    }
    return 0;
}

printf函数通过换行符来刷新字符串,因没有换行符,所以程序员的美誉之词并不会输出,调用exit函数将文件内容从缓冲区写入文件,所以在终端上我们可以看到子进程的两条输出语句。相应的_exit函数直接将缓冲区中的数据丢掉,我们只能看见父进程中第一条带有换行符的输出语句
输出结果:
这里写图片描述
正好验证了我们的猜测。
文章难免会有所疏漏和考虑不全的地方,如果有问题,欢迎指正哦。

猜你喜欢

转载自blog.csdn.net/Cxinsect/article/details/81429818
今日推荐