exit、_exit、函数与return的不同

 

说明:只供学习交流,装载请注明出处

 

正常中止一个程序,可以使用从main函数中返回、调用exit函数或_exit函数的方法。从main函数中返回这一方法,常用于获得程序返回值这一场合。这时,除了需要定义main函数的类型外,在程序中还需要使用return语句。使用这一方法退出程序只能用于主函数中,用在子程序中只能返回上一级调用程序。

 

exit函数和_exit函数可以用在子程序中。程序在执行到这两个函数处,会自动结束并跳回到操作系统中。当然,也可以将这两个函数用在main函数中。与使用return相比,exit_exit是不考虑返回类型的,也就是说,main的类型可以是void或任意类型。

 

一个简单的例子:

#include <stdio.h>
#include <stdlib.h>

void Exit_Test(void)
{
        printf("Hello linux!\n");
        exit(0);
}

int main(void)
{
        Exit_Test();

        printf("Hello word!\n");

        return (0);
}

输出结果:
[root@localhost test]# ./exit 
Hello linux!


 

说明:程序并没有输出“helloword!”,因为程序运行到exit出了直接退出并跳到操作系统中。

 

 

exit函数:

exit函数的定义信息如下表:

 

头文件

#include <stdlib.h>

函数原型

void exit(int status)

返回值

成功

失败

是否设置errno

——

——

——

 

说明:调用exit函数结束进程,并将(status & 0377)获得的结果返回给父进程。使用exit函数结束进程时,会首先执行使用atexit函数注册的函数,然后调用on_exit函数中清理动作。函数执行顺序与注册的顺序相反。

参数status为退出进程时的状态,父进程将获得该状态值。C语言标准指定了EXIT_SUCCESSEXIT_FAILURE作为程序正常结束和异常中止的两个宏。

 

为了说明使用exit函数退出程序是会执行的相关的动作,这里给出一个简单的实例。程序用atexit注册了一个进程退出时的处理函数,该处理函数只是显示一段文字信息。main函数退出时将调用exit函数,这样进程就会在退出时自动调用atexit注册的处理函数。

atexit函数定义如下:

int atexit(void (*function) (void));

atexit在成功注册回调函数后会返回0值,否则返回返回非0值。

 

代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

void do_at_exit(void)
{
        printf("You can see the output when the program terminates\n");
}

int main(void)
{
        int flag;

        flag = atexit(do_at_exit);

        if ( flag != 0 )
        {
                printf("Cannot set exit function!\n");
                return (EXIT_FAILURE);
        }

        exit(EXIT_SUCCESS);
}
运行结果:
[root@localhost test]# ./atexit 
You can see the output when the program terminates
[root@localhost test]# 


 

说明:在main中调用return函数同样会在程序退出时执行使用atexit注册的处理动作。因此,使用return代替exit函数同样会获得相同的结果。

 

_exit函数:

exit函数类似,_exit函数同样可以用于退出进程,这两个函数存在一定的区别。在介绍vfork函数的使用时,提到了子进程的退出只能使用_exit函数,具体原因并没有阐述。这里首先介绍其定义,然后通过实例来说明它们之间的区别。

 

_exit函数的定义如下表:

 

头文件

#include <unistd.h>

函数原型

void _exit(int status)

返回值

成功

失败

是否设置errno

——

——

——

 

说明:_exit函数将立即结束调用它的进程,与进程相关的任何打开的文件描述符都将关闭,进程的子进程都将变为init进程(进程号为1)的子进程。

参数status为退出进程时的状态,父进程将获得该状态值。C语言标准指定了EXIT_SUCCESSEXIT_FAILURE作为程序正常结束和异常中止的两个宏。

 

我们同样使用上面的那个实例,只是把exit该为_exit退出,其他的都是一样,之所以使用同一个例子是为了说明_exit退出程序时,不会执行atexit注册的处理函数。

实例:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

void do_at_exit(void)
{
        printf("You can see the output when the program terminates\n");
}

int main(void)
{
        int flag;

        flag = atexit(do_at_exit);

        if ( flag != 0 )
        {
                printf("Cannot set exit function!\n");
                return (EXIT_FAILURE);
        }

        _exit(EXIT_SUCCESS);
}
运行结果:
[root@localhost test]# ./atexit 
[root@localhost test]#


 

exit函数与_exit函数的区别:

1):exit函数只是在ANSI C中说明的,而_exit函数是在POSIX标准中说明的。

2):exit函数将终止调用进程,在退出程序之前所有文件关闭,标准输入输出的缓冲区被清空,并执行在atexit注册的回调函数;_exit终止调用进程,但不关闭文件,不清除标准输入输出缓存区,也不调用在atexit注册的回调函数。

 

说明:在系统调用fork创建的子进程中,一般情况下尽量不要使用exit函数退出子进程。因为exit会导致标准输入输出的缓冲区被清空。对应C++程序,问题可能会更严重。exit函数有可能导致静态目标文件中的析构函数被错误执行。使用exit函数时,必须保证exit在进入main函数后只会被调用一次。而使用vfork时,由于父子进程共享虚拟内存空间,子进程使用exit将会影响父进程的状态。

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值