您的位置:首页 > 理论基础 > 计算机网络

进程终止函数:abort, atexit, exit, _exit, _Exit http://blog.sina.com.cn/s/blog_605f5b4f0100x3v0.html

2015-09-21 19:49 711 查看
标签:


exit


_exit


return


atexit


结束进程


缓冲区


it

分类: C
#include <stdlib.h>

void exit(int status);

void _Exit(int status);

int atexit( void(*func)(void) );

#include <unistd.h>

void _exit(int status); // windows 也有_exit(int status)函数,但是具体和linux的有区别,稍后会讲。

exit, _exit, _Exit 都是进程终止函数。

abort : 产生 SIGABRT 信号。非正常退出,即在程序碰到灾难性错误时强制退出。由于是非正常退出,因此不会做其它任何操作。

atexit 是在执行 exit 函数时设置要作的工作,实际就是调用要在进程退出想让程序执行的函数。

其参数是要调用的函数地址。参数函数是一个无参数无返回值的函数。atexit可以登记32个函数,这些函数由 exit 函数自动调用,登记的顺序和调用的顺序相反,即最后登记的先执行。同一函数登记多次也会调用多次。

exit :是一个C库标准函数。此函数执行会首先调用由 atexit注册的函数,然后执行关闭所有标准IO流,刷新流缓冲区等操作。对于常用的有返回值的 return 调用,相当于调用了 exit 。如 return(0)== exit(0);

_exit : 是一个系统调用。此函数不会调用 atexit 注册的函数,也不会运行信号处理程序。对标准IO流的缓冲区是否进行刷新取决于该函数在系统中的实现。一般UNIX下不会刷新。 exit函数会调用此函数。(在windows下的_exit函数会对标准IO流的缓冲进行刷新)

_Exit : 是一个C库标准函数。其动作类似 _exit 。

exit和_exit函数

exit和_exit函数用于正常终止一个程序: _exit立即进入内核, exit则先执行一些清除处理(包括调用执行各终止处理程序,关闭所有标准I / O流等),然后进入内核

#include <stdlib.h>void exit(int status);#include <unistd.h>void _exit (int status) ;使用不同头文件的原因是:exit是由ANSI C说明的,而_exit则是由POSIX.1说明的

由于历史原因, exit函数总是执行一个标准I/O库的清除关闭操作:对于所有打开流调用fclose函数

注意,内核使程序执行的唯一方法是调用一个e x e c函数。进程自愿终止的唯一方法是显式或隐式地(调用e x i t )调用_ e x i t。进程也可非自愿地由一个信号使其终止exit本身不是系统调用,而是一个C标准库的函数而已,在stdlib里面,系统调用是_exit内部实现去完成的

如下代码说明了exit终止了一个程序

#include<stdio.h>

#include<stdlib.h>

#include<conio.h>

int main()

{

int status;

printf("Enter either 1 or 2\n");

status = getch();

exit(status - '0');

printf(" You'll never see this\n");

return 0;

}

输出结果为:





如下代码说明了exit终止程序之前调用atexit以及调用的函数的顺序。

#include<stdio.h>

#include<stdlib.h>

void exit_fn1(void)

{

printf("Exit function #1 called\n");

}

void exit_fn2(void)

{

printf("Exit function #2 called\n");

}

int main(void)

{

atexit(exit_fn1);

atexit(exit_fn2);

// return 0 ;

exit(0);

// _exit(0);

// abort();

}

使用exit(0)和return 0的输出结果相同,如下所示:





可以看到先注册的exit_fn1后执行。并且注册的函数无参数无返回值。另外,如果使用_exit(0),则不会有输出结果,因为_exit(0)不执行atexit注册的函数。

如下是使用_exit(0)和exit(0)对标准IO缓冲区是否刷新的比较操作:

#include<stdlib.h>

#include<stdio.h>

#include<unistd.h>

int main()

{

printf("output begin\n");

printf("output in buffer");

_exit(0);

//exit(0);

return 0;

}

在linux和windows下执行exit均会输

output begin

content buffer

而在linux执行_exit则只会输出output begin,但是在windows下_exit仍同exit的输出

对应每个打开的文件,在内存中都有一片缓冲区。每次读文件时,会读出若干条记录,这样下次读文件就可以直接从内存的缓冲区中读取,每次写文件的时候也仅仅是写入内存中的缓冲区,等满足了一定条件(达到一定数量,遇到特定字符如换行符\n和文件结束符EOF),再将缓冲区中的内容一次性写入文件。

printf会根据参数format字符串来转换并格式化数据,然后将结果写到标准输出设备,直到出现字符串结束符\0为止。

可见,exit将未出现换行符的语句保存到标准输出文件。而由于第二条printf没有满足特定条件,只是保存在缓冲区,使用_exit()函数直接将进程关闭,缓冲区就会丢失。

return与exit的区别

在进程操作中exit是结束当前进程或程序并把控制权返回给调用该程序或者进程的进程即父进程并告诉父进程该当前进程的运行状态,而return是从当前函数返回,如果是在main函数中,main函数结束时隐式地调用exit函数,自然也就结束了当前进程。

return是语言级别的,它表示了调用堆栈的返回;而exit是系统调用级别的,它表示了一个进程的结束。exit函数是退出应用程序,并将应用程序的一个状态返回给OS,这个状态标识了应用程序的一些运行信息。

在main函数里面return(0)和exit(0)是一样的,子函数用return返回;而子进程用exit退出,调用exit时要调用一段终止处理程序,然后关闭所有I/O流。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: