exit、_exit,return的区别

原文:http://blog.csdn.net/firefly_2002/article/details/7960595

1. exit用于结束正在运行的整个程序,它将参数返回给OS,把控制权交给操作系统;而return 是退出当前函数,返回函数值,把控制权交给调用函数

2. exit是系统调用级别,它表示一个进程的结束;而return 是语言级别的,它表示调用堆栈的返回。简单地说,exit是退出整个进程,而return是结束一个函数。
3. 在main函数结束时,会隐式地调用exit函数,所以一般程序执行到main()结尾时,则结束主进程。exit将删除进程使用的内存空间,同时把错误信息返回给父进程。

4. void exit(int status); 一般status为0,表示正常退出,非0表示非正常退出。

5.exit函数声明在stdlib.h,中_exit函数在“unistd.h”头文件中。

exit()函数与_exit()函数最大的区别就在于exit()函数在调用exit系统调用之前要检查文件的打开情况,把文件缓冲区中的内容写回文件,就是图中的"清理I/O缓冲"一项。

exit() 函数定义在 stdlib.h 中,而 _exit() 定义在 unistd.h 中。 exit() _exit() 都用于正常终止一个进程。但 _exit() 直接是一个 sys_exit 系统调用,而 exit() 则通常是普通函数库中的一个函数。它会先执行一些清除操作,例如调用执行各终止处理函数、关闭所有标准 IO 等,然后调用 sys_exit。如下面这个例子:

static void myexit1()
{
     printf("first exit handler\n");
}

static void myexit2()
{
     printf("second exit handler\n");
}
 
int main()
{
        int i=0;
     atexit(myexit2);
     atexit(myexit1);
     atexit(myexit1);
     printf("main is done\n");
//     return 0;//会执行清理动作,因为main函数退出后,进程还在。进程在退出之前会会执行清除操作。
exit(0);//进程在退出之前会会执行清除操作。调用sys_exit.
//_exit(0);//进程直接退出不会执行清除擦作。调用sys_exit.

}

atexit终止处理程序:

ISO C规定, 一个进程最多可登记32个终止处理函数, 这些函数由exit按登记相反的顺序自动调用。如果同一函数登记多次, 也会被调用多次。


这样看上去在main函数中return跟exit貌似并无明显区别。下面就举个例子证明一下return和exit的区别。

int main(void)
{
pid_t pid;
int count=0;
int childpid;
int status;
pid=vfork();//shared data section,主进程会等待由vfork创建的子进程退出。 vfork 保证子进程先运行,在调用exec 或exit 之前与父进程数据是共享的,在它调用exec
if(pid==0)
{
        printf("child: count=%d\n",count);
        childpid=getpid();
        printf("child: getpid=%d\n",getpid());
        printf("child's father: getppid=%d\n",getppid());
        count++;printf("child: count=%d\n",count);
     return 0;//会重复不断地创建子进程或者会死锁。因为子进程没有退出,而父进程一直在等待子进程退出。
     //   exit(0); //ok

      // _exit(0); //ok

}
else
{
        waitpid( pid, &status, 0 );
        printf("\nfather: pid=%d\n",pid);
        printf("father: count=%d\n",count);
        return(0);
}

运行结果说明:vfrok时父、子进程共享数据段,fork  ():子进程拷贝父进程的数据段,代码段 。如果,vfork子进程中,使用return返回时,出现死锁。解决办法:

1.将vfrok改为fork,父进程使用waitpid。但是这样的缺点是子进程拷贝了父进程的的数据段和代码段,而一般情况下子进程都会指向exec()新的代码段。

这样他们的数据也是独立的,只是拷贝,不是共享。看需求而定吧。

2.如果必须使用vfrok,则子进程必须使用exit或者_exit去退出。

这说明return和exit还是有本质上的区别的。

对于单进程来说,其中任意一段代码执行了exit都会导致进程退出,而return则只是函数退出。main函数的结束会隐式调用exit。


发布了21 篇原创文章 · 获赞 5 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/linchuanzhi_886/article/details/38467305