• linux exit 和 _exit的区别


    今天仔细看了一下exit和_exit这两个函数的区别,实际上exit也是调用了_exit退出函数的,只不过在调用_exit之前,exit还进行了一些多余的工作,也正是因为这样,相比起来exit就没有那么接近底层的系统调用,更应该说是包装过的标准C库函数。_exit包含在头文件unistd.h中,exit包含在头文件stdlib.h中,我们来查看一下他们的函数原型。

    man _exit :

    很显然,_exit函数做这三件事情:

    1. 让调用的进程马上终止。

    2.关闭所有由这个进程打开的文件描述符。

    3.调用进程的所有子进程都被初始化init进程收养,调用进程将发送SIGCHLD给他的父进程(这都是因为他即将要退出了,当然要安顿好自己的孩子和告别父母啦)。

    man exit:

    exit则做了这几件事:

    1.按axexit或者on_exit注册时相反的顺序调用所有由它注册的函数(出口函数),可以把on_exit看作atexit的扩展。(这使得我们可以指定在程序终止时执行自己的清理动作.例如,保存程序状态信息于某个文件,解开对共享数据库上的锁等。)如果有任意一个注册的函数不返回(比如这个函数call _exit或者用像SIGKILL这样的信号把自己干掉了),那么剩余的注册函数都不会得到执行,而且接下来更深层次的exit都不会被执行。如果一个函数被注册了多遍,那么也会按顺序执行多遍(这些是atexit的特性)

    2.所有打开的输入输出流都将被清空和关闭,换句话说就是把缓冲区的内容写回文件中。那些用tmpfile函数创建的临时文件都将被移除。

    3.调用_exit。

    所以,总的来说,exit就是对_exit进行了一些包装,使得整个退出的过程显得不那么粗暴,他们俩的共同点就是都会关闭文件描述符,都会清空内存,但是exit还会额外地清空输入输出流缓存,移除临时创建的文件,调用注册好的出口函数等等。

    现在我们只需要用一个小例子来观察他们俩的区别就可以了:

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    
    int main(int argc, char const *argv[])
    {
        printf("hello
    ");
        printf("  hi");
        exit(0);
        //_exit(0);
        return 0;
    }

    对于上面这段代码,我们的执行结果为:

    而我们把代码改一改:

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    
    int main(int argc, char const *argv[])
    {
        printf("hello
    ");
        printf("  hi");
        //exit(0);
        _exit(0);
        return 0;
    }

    结果就变成了:

    这显然是因为_exit并没有进行缓冲区的清空等操作,而exit则会把缓冲的内容都清空。

    参考博客:

    http://blog.chinaunix.net/uid-12461657-id-3140887.html

  • 相关阅读:
    threading.Timer 返回值
    AttributeError: 'FileEventHandler' object has no attribute 'core'
    JS限制内容显示多少个字符
    #1115
    python实现读取文件夹下所有文件内容
    【css】响应式布局 @media媒介 适配平板手机
    js实现canvas保存图片为png格式并下载到本地
    Css+Div设置电脑端显示,手机端不显示代码
    禁止F12代码
    git pull fatal: unable to access OpenSSL SSL_read: Connection was reset, errno 10054
  • 原文地址:https://www.cnblogs.com/Cccarl/p/6798684.html
Copyright © 2020-2023  润新知