原文:http://blog.csdn.net/firefly_2002/article/details/7960595
1. exit用于结束正在运行的整个程序,它将参数返回给OS,把控制权交给操作系统;而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。