linux中的exit

C标准定义了下面的退出函数:

#include <stdlib.h>

void exit(int status);

void _Exit(int status);

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

函数功能介绍如下:

void exit(int status)

该函数终止调用的程序。status传递给系统用于父进程恢复。程序退出之前,exit()调用所有以atexit()注册的函数,清空所有打开的<stdio.h> FILE*流的缓冲区并关闭流,然后删除所有由tmpfile()创建的临时文件。进程退出时,内核关闭所有剩下的已打开文件(即那些由open()、creat()或文件描述符继承打开的文件),释放其地址空间,然后释放所有其他使用的资源。exit()从不返回。

void _Exit(int status)

该函数基本上与POSIX的_exit()函数相同。

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

function是一个函数指针,指向程序退出时候调用的一个回调函数。exit()在其关闭文件和终止之前调用该回调函数。这个想法在于程序能够在最终关闭之前提供一个或者多个运行的清理函数。提供一个函数被成为注册该函数。

atexit()成功时返回0,出错时返回-1并设置相应的errno。

下面的程序没有有用的功能,但它演示了如何使用atexit():

void callback1(void){printf("callback called\n");}

void callback2(void)(printf("callback called\n");}

void callback3(void)(printf("callback called\n");}

int main(int argc,char* argv[])

{

printf("registering callback1\n");atexit(callback1);

printf("registering callback2\n");atexit(callback2);

printf("registering callback3\n");atexit(callback3);

printf("exiting now\n");

exit(0);

}

下面是程序的运行结果:

$atexit

registering callback1

registering callback2

registering callback3

exiting now

callback3 called

callback2 called

callback1 called

正如上例所示,使用atexit()注册的函数运行时的顺序和注册的顺序相反:最近注册的最先运行(这也称为后进先出(last-in-first-out),缩写为LIFO)。

POSIX定义了_exit()函数。与exit()不同,exit()调用回调函数并进行<stdio.h>清理,_exit()是“立即死亡”的函数:

#include <unistd.h>

void _exit(int status);

_exit终止调用进程,但不关闭文件,不清除输出缓存,也不调用出口函数。exit函数将终止调用进程。在退出程序之前,所有文件关闭,缓冲输出内容将刷新定义,并调用所有已刷新的“出口函数”(由atexit定义)。

实际上,ISO C的_Exit()函数与_exit()相同。C函数指出_Exit()是否调用以atexit()注册的函数并关闭打开的文件取决与实现。对于GLIBC系统,可能不会,即_Exit()与_exit()表现相似。

使用_exit()的时机是在fork()产生的子进程中调用exec()失败的时候。这种情况下,不需要使用通常的exit(),因为它会清空所有由FILE*流保存的缓冲区数据。随后父进程清空其缓冲区拷贝时,导致缓冲的数据被写了两次;显然这不是很恰当。

例如,加入你运行了一个shell命令,并且自己调用fork()和exec()。代码可能如下所示:

char *shellcommand="...";

pid_t child;

if((child=fork())==0){

execl("/bin/sh","sh","-c",shellcommand,NULL);

_exit(errno==ENOENT?127:126);

}

errno测试和退出值采取了POSIX shell所使用的惯例。如果要求的程序没有退出(ENOENT——目录中没有它的项),则退出值为127。否则,文件同样退出,但由于其他原因不能够被exec()执行,则退出状态为126。在你自己的程序中采取这个惯例将会是个好主意。

简言之,为了更好地使用exit()和atexit(),你应该遵循一下规则:

1、定义一个较小的退出状态值的集合,你的程序使用该集合中的值与其调用者进行通信。在你的代码中使用#define常量或enum定义这些值。

2、决定是否有必要与atexit()一起使用回调函数。如果有必要,则在main()中适当地方注册这些函数;例如,在解析选项之后以及初始化任何回调函数可能清除的数据结构之后,记住函数以LIFO(last-in-first-out)顺序进行调用。

3、如果出错,在任一地方都可以使用exit()从程序退出,退出是能够发生的正确行为。同时使用你定义的错误代码。

4、main()函数是个例外,你可以在其中使用return。我们自己的风格是,通常出问题时使用exit(),而如果一切正常,在main()结尾处使用“return 0”。

5、如果调用exec()失败,则在子进程中使用_exit()或_Exit()。

时间: 2024-08-08 05:35:32

linux中的exit的相关文章

Linux中exit与_exit的区别

在exit,_exit的区别 - exit()与_exit()函数的区别(Linux系统中)2012-03-20 15:19:53 分类: LINUX 注:exit()就是退出,传入的参数是程序退出时的状态码,0表示正常退出,其他表示非正常退出,一般都用-1或者1,标准C里有EXIT_SUCCESS和EXIT_FAILURE两个宏,用exit(EXIT_SUCCESS);可读性比较好一点. 作为系统调用而言,_exit和exit是一对孪生兄弟,它们究竟相似到什么程度,我们可以从Linux的源码中

Linux中tomcat开机启动配置脚本【参考其他文章的总结备忘录】

参考文章http://blog.sina.com.cn/s/blog_a57562c80101ic47.html http://blog.csdn.net/cheng168520/article/details/4312828 http://blog.sina.com.cn/s/blog_7f395ece0100ti5y.html 以前在自己本机上安装过一个Linux,后台应为系统崩溃,以前配置的开机启动脚本.数据库主从双备份.负载均衡等都没了,所以现在在重新配置一次,赶紧做个笔记防止自己以后又

Linux中的man

1.查看命令的帮助信息 man mkdir 2.查看服务配置文件的帮助信息 man services 说明: a.如果没有man通过yum install man安装 b.如果命令和服务同名了,那就指定清楚 1.Linux中通过whereis xxx可以看到xxx的命令和帮助文档地址 2.帮助文档如果是xxx.1.gz则xxx为命令 3.帮助文档如果是xxx.5.gz则xxx为服务 4.这时候使用man的时候可以加上1或者5来指定,例如:man 5 xxx c.只能查看非bash级别的命令 d.

linux中如何查询端口被占用的情况

今日要运用python写一个端口勘探的小程序,以检测一些特定的效劳端口有没有被占用,突然发现自个竟然不知道在linux中怎么查询端口被占用的情况,天呐,从速学习一下. Linux如何查看端口 1.lsof -i:端口号 用于查看某一端口的占用情况,比如查看8000端口使用情况,lsof -i:8000 # lsof -i:8000 COMMAND   PID USER   FD   TYPE  DEVICE SIZE/OFF NODE NAME lwfs    22065 root    6u 

Linux中的僵尸进程和孤儿进程

在UNIX里,除了进程0(即PID=0的交换进程,Swapper Process)以外的所有进程都是由其他进程使用系统调用fork创建的,这里调用fork创建新进程的进程即为父进程,而相对应的为其创建出的进程则为子进程,因而除了进程0以外的进程都只有一个父进程,但一个进程可以有多个子进程.        操作系统内核以进程标识符(Process Identifier,即PID)来识别进程.进程0是系统引导时创建的一个特殊进程,在其调用fork创建出一个子进程(即PID=1的进程1,又称init)

Linux 中的文件共享服务

Linux 中的文件共享服务 ============================================================================== 概述:    本章将主要介绍文件共享服务中的ftp服务,内容包括:ftp的程序环境,配置文件的相关介绍,以及如何配置基于虚拟用户的vsftpd服务 文件服务 1)介绍 ★ftp: 应用层,C/S架构,文件共享:file transfer protocol: ★nfs,cifs:文件系统接口,网络文件系统: ☉n

应用Oracle(Linux中的安装)

Linux中安装Oracle,不同于windows. Linux在安装时,要作些必要的分区配置,以便进行Oracle的安装: 同时需要创建专门的数据库用户和组,并配置环境变量. root登录 使用 root 来配置 Oracle 环境 其中**检查环境**部分,需要在安装 Oracle 检查和配置环境 检查环境 1.swap空间 # swap 空间大小,应满足以下条件 # 内存 1~2 G,swap 空间大小应为2倍内存 # 内存 2~16 G, swap 空间大小等同于内存 # 内存 > 16

Linux 中使用 expect

expect 是由 Don Libes 基于 Tcl 语言开发并广泛用于交互式操作和自动化测试场景中,通过 expect 可以让 shell脚本无需人为干预自动进行交互式通信. expect 的核心功能是根据设定好的匹配形式,以执行相匹配的动作,进入自动化的人机交互. 以下以Ubantu上Demo做案例说明: 安装 expect sudo apt-get install expect  实例 以 SSH 登陆本机在$HOME下创建kitty文件夹作为例子,下面是 shell脚本源码. #!/us

linux中解决SSH连接慢问题

现在连接linux服务器一般都是使用SSH远程连接的方式.最近新装了一台服务器,发现telnet时速度很快,ping时一切也正常,但SSH连接的时候却很慢.经过网上资料查询,大致是有以下几种原因: 1.SERVER的SSHD会去DNS查找访问的CLIENT IP的HOSTNAME,如果DNS不可用或者没有相关记录,就会消耗一段时间. 2.在authentication gssapi-with-mic有时候也会消耗一段时间 一.测试查找具体原因: 1.使用ssh -v host进行debug #