c语言exit函数怎么用

今天给大家讲的是linux命令exit的一个用法和区别,荣新教育提示:这两天北京空气不是很好,同学们注意呼吸道疾病的感染。好了下面一起来看看吧。

c语言exit函数怎么用

注:exit()就是退出,传入的参数是程序退出时的状况码,0表明正常退出,其他表明非正常退出,一般都用-1或许1,规范C里有EXIT_SUCCESS和EXIT_FAILURE两个宏,用exit(EXIT_SUCCESS);可读性比较好一点。

作为体系调用而言,_exit和exit是一对孪生兄弟,它们终究类似到什么程度,咱们能够从Linux的源码中找到答案:

#define __NR__exit __NR_exit /* 摘自文件include/asm-i386/unistd.h第334行 */

"__NR_"是在Linux的源码中为每个体系调用加上的前缀,请注意第一个exit前有2条下划线,第二个exit前只有1条下划线。 这时随意一个懂得C语言而且头脑清醒的人都会说,_exit和exit没有任何差异,但咱们还要讲一下这两者之间的差异,这种差异首要体现在它们在函数库中的界说。_exit在Linux函数库中的原型是:

#i nclude void _exit(int status);

和exit比较一下,exit()函数界说在stdlib.h中,而_exit()界说在unistd.h中,从名字上看,stdlib.h好像比 unistd.h高档一点,那么,它们之间到底有什么差异呢? _exit()函数的效果最为简略:直接使进程中止运转,铲除其运用的内存空间,并毁掉其在内核中的各种数据结构;exit() 函数则在这些基础上作了一些包装,在履行退出之前加了若干道工序,也是由于这个原因,有些人以为exit现已不能算是朴实的体系调用。 exit()函数与_exit()函数最大的差异就在于exit()函数在调用exit体系调用之前要检查文件的翻开状况,把文件缓冲区中的内容写回文件,就是"整理I/O缓冲"。

exit()在完毕调用它的进程之前,要进行如下过程:

1.调用atexit()注册的函数(出口函数);按ATEXIT注册时相反的顺序调用一切由它注册的函数,这使得咱们能够指定在程序停止时履行自己的整理动作.例如,保存程序状况信息于某个文件,解开对同享数据库上的锁等.

2.cleanup();封闭一切翻开的流,这将导致写一切被缓冲的输出,删去用TMPFILE函数树立的一切暂时文件.

3.最终调用_exit()函数停止进程。

_exit做3件事(man): 1,Any open file deors belonging to the process are closed 2,any children of the process are inherited by process 1, init 3,the process‘s parent is sent a SIGCHLD signal

exit履行完整理作业后就调用_exit来停止进程。

此外,别的一种解说:

简略的说,exit函数将停止调用进程。在退出程序之前,一切文件封闭,缓冲输出内容将改写界说,并调用一切已改写的“出口函数”(由atexit界说)。

_exit:该函数是由Posix界说的,不会运转exit handler和signal handler,在UNIX体系中不会flush规范I/O流。

简略的说,_exit停止调用进程,但不封闭文件,不铲//www.58yuanyou.com除输出缓存,也不调用出口函数。

一起:

不管进程是怎么停止的,内核都会封闭进程翻开的一切file deors,开释进程运用的memory!

更详细的介绍:

Calling exit() The exit() function causes normal program termination.

The exit() function performs the following functions:

1. All functions registered by the Standard C atexit() function are called in the reverse order of registration. If any of these functions calls exit(), the results are not portable. 2. All open output streams are flushed (data written out) and the streams are closed.

3. All files created by tmpfile() are deleted.

4. The _exit() function is called. Calling _exit() The _exit() function performs operating system-specific program termination functions. These include: 1. All open file deors and directory streams are closed.

2. If the parent process is executing a wait() or waitpid(), the parent wakes up and status i//www.58yuanyou.coms made available.

3. If the parent is not executing a wait() or waitpid(), the status is saved for return to the parent on a subsequent wait() or waitpid(). 4. Children of the terminated process are assigned a new parent process ID. Note: the termination of a parent does not directly terminate its children. 5. If the implementation supports the SIGCHLD signal, a SIGCHLD is sent to the parent. 6. Several job control signals are sent.

为安在一个fork的子进程分支中运用_exit函数而不运用exit函数? ‘exit()’与‘_exit()’有不少差异在运用‘fork()’,特别是‘vfork()’时变得很 杰出。

‘exit()’与‘_exit()’的根本差异在于前一个调用施行与调用库里用户状况结构(user-mode constructs)有关的铲除作业(clean-up),而且调用用户自界说的铲除程序 (自界说铲除程序由atexit函数界说,可界说屡次,并以倒序履行),相对应,_exit函数只为进程施行内核铲除作业。 在由‘fork()’创立的子进程分支里,正常状况下运用‘exit()’是不正确的,这是 由于运用它会导致规范输入输出(stdio: Standard Input Output)的缓冲区被清空两次,而且暂时文件被出乎意料的删去(暂时文件由tmpfile函数创立在体系暂时目录下,文件名由体系随机生成)。在Cwww.58yuanyou.com++程序中状况会更糟,由于静态目标(static objects)的析构函数(destructors)能够被过错地履行。(还有一些特别状况,比方看护程序,它们的父进程需求调用‘_exit()’而不是子进程;适用于绝大多数状况的根本规则是,‘exit()’在每一次进入‘main’函数后只调用一次。) 在由‘vfork()’创立的子进程分支里,‘exit()’的运用将愈加风险,由于它将影响父进程的状况。

#include ; #include int glob = 6; /* external variable in initialized data */ int main(void) { int var; /* automatic variable on the stack */ pid_t pid; var = 88; printf("before vfork\n"; /* we don‘t flush stdio */ if ( (pid = vfork()) < 0) printf("vfork error\n"; else if (pid == 0) { /* child */ glob++; /* modify parent‘s variables */ var++; exit(0); /* child terminates */ //子进程中最好仍是用_exit(0)比较安全。 } /* parent */ printf("pid = %d, glob = %d, var = %d\n", getpid(), glob, var); exit(0); } 在Linux体系上运转,父进程printf的内容输出:pid = 29650, glob = 7, var = 89

子进程 封闭的是自己的, 尽管他们同享规范输入、规范输出、规范犯错等 “翻开的文件”, 子进程exit时,也不过是递减一个引证计数,不可能封闭父进程的,所以父进程仍是有输出的。

但在其它UNIX体系上,父进程可能没有输出,原 因是子进程调用了e x i t,它改写封闭了一切规范I / O流,这包含规范输出。尽管这是由子进程履行的,但却是在父进程的地址空间中进行的,所以一切受到影响的规范I/O FILE目标都是在父进程中的。当父进程调用p r i n t f时,规范输出已被封闭了,所以p r i n t f回来- 1。

在Linux的规范函数库中,有一套称作"高档I/O"的函数,咱们熟知的printf()、fopen()、fread()、fwrite()都在此 列,它们也被称作"缓冲I/O(buffered I/O)",其特征是对应每一个翻开的文件,在内存中都有一片缓冲区,每次读文件时,会多读出若干条记载,这样下次读文件时就能够直接从内存的缓冲区中读取,每次写文件的时分,也仅仅是写入内存中的缓冲区,等满意了必定的条件(到达必定数量,或遇到特定字符,如换行符和文件完毕符EOF), 再将缓冲区中的 内容一次性写入文件,这样就大大增加了文件读写的速度,但也为咱们编程带来了一点点费事。假如有一些数据,咱们以为现已写入了文件,实际上由于没有满意特 定的条件,它们还仅仅保存在缓冲区内,这时咱们用_exit()函数直接将进程封闭,缓冲区中的数据就会丢失,反之,假如想确保数据的完整性,就必定要运用exit()函数。

Exit的函数声明在stdlib.h头文件中。

_exit的函数声明在unistd.h头文件当中。

下面的实例比较了这两个函数的差异。printf函数就是运用缓冲I/O的方法,该函数在遇到“\n”换行符时主动的从缓冲区中将记载读出。实例就是利用这个性质进行比较的。

exit.c源码

#include #include int main(void) 原由网{ printf("Using exit...\n"); printf("This is the content in buffer"); exit(0); }

输出信息:

Using exit...

This is the content in buffer

#include #include int main(void) { printf("Using exit...\n"); //假如此处不加“\n”的话,这条信息有可能也不会显现在终端上。 printf("This is the content in buffer"); _exit(0); }

则只输出:

Using exit...

阐明:在一个进程调用了exit之后,该进程并不会马上彻底消失,而是留下一个称为僵尸进程(Zombie)的数据结构。僵尸进程是一种十分特别的进程,它简直现已抛弃了一切的内存空间,没有任何可履行代码,也不能被调度,仅仅在进程列表中保存一个方位,记载该进程的退出原由网状况等信息供其它进程收集,除此之外,僵尸进程不再占有任何内存空间。

#include ;

int main() { printf("%c", ‘c‘); _exit(0); }文章源自荣新教育官网:www.vfast.com.cn欢迎访问,转载需注明出处

内容版权声明:除非注明原创否则皆为转载,再次转载请注明出处。

文章标题: c语言exit函数怎么用

文章地址: www.58yuanyou.com/jiqiao/346854.html

相关推荐