linux下exit()和_exit()区别

平时一直在用exit()函数,但是今天看源码时竟然看到了_exit()函数,想知道它们的区别,所以就查查资料,写了下来!

  #include<stdlib.h>
  void exit(int status);

不像fork那么难理解,从exit的名字就能看出,这个系统调用是用来终止一个进程的。无论在程序中的什么位置,只要执行到exit系统调用,进程就会停止剩下的所有操作,清除包括PCB在内的各种数据结构,并终止本进程的运行。请看下面的程序:

#include<stdlib.h>
#include <stdio.h>
main()
{
   printf("this process will exit!\n");
   exit(0);//程序在次退出,不会再向下执行。
   printf("never be displayed!\n");
}

运行结果:

我们可以看到,程序并没有打印后面的"never be displayed!\n",因为在执行到exit(0)时,进程就已经终止了,不会再向下执行,直接退出。exit 系统调用带有一个整数类型的参数status,我们可以利用这个参数传递进程结束时的状态:

(1) 0表示没有意外的正常结束;

(2)其他的数值表示出现了错误,进程非正常结束。

我们在实际编程时,可以用wait系统调用接收子进程的返回值,从而针对不同的情况进行不同的处理。

     linux下exit()和_exit()的用法及区别:

exit和_exit作为系统调用而言,_exit和exit是一对孪生兄弟。通常我们会认为,他们之间没有什么区别:但是没有区别会有两个函数,你要知道程序猿虽然苦但不笨,这种事儿发生的概率比较低,所以答案是否定的。这种区别主要体现在它们在函数库中的定义,_exit在Linux函数库中的原型是:

  #include<unistd.h>
  void _exit(int status);

(1)exit()函数定义在 stdlib.h中;而_exit()定义在unistd.h中,

(2)_exit()函数的作用最为简单:直接使进程停止运行,清除其使用的内存空间,并销毁其在内核中的各种数据结构;exit()函数则在这些基础上作了一些包装,在执行退出之前加了若干道工序,也是因为这个原因,有些人认为exit已经不能算是纯粹的系统调用。

因此,exit()函数与_exit()函数最大的区别就在于:exit()函数在调用exit系统调用之前要检查文件的打开情况,把文件缓冲区中的内容写回文件,就是“清理I/O缓冲”,而_exit()则是直接退出,不管缓冲区的数据,直接停止,容易造成数据的丢失。

在Linux 的标准函数库中,有一套称作“高级I/O”的函数,我们熟知的printf()、fopen()、fread()、fwrite()都在此列,它们也被称作“缓冲I/O(buffered I/O)”,其特征是对应每一个打开的文件,在内存中都有一片缓冲区,每次读文件时,会多读出若干条记录,这样下次读文件时就可以直接从内存的缓冲区中读取,每次写文件的时候,也仅仅是写入内存中的缓冲区,等满足了一定的条件(达到一定数量,或遇到特定字符,如换行符\n和文件结束符EOF),再将缓冲区中的内容一次性写入文件,这样就大大增加了文件读写的速度,但也为我们编程带来了一点点麻烦。如果有一些数据,我们认为已经写入了文件,实际上因为没有满足特定的条件,它们还只是保存在缓冲区内,这时我们用_exit()函数直接将进程关闭,缓冲区中的数据就会丢失,反之,如果想保证数据的完整性,就一定要使用exit()函数。

请看以下例程:

#include<stdlib.h>
int main()
{
   printf("output begin\n");
   printf("content in buffer\n");
   exit(0);//输出前两句,程序在次退出;
}

运行结果:

从运行结果来看,exit(0)是函数正常的退出;

#include<unistd.h>
int main()
{
    printf("output begin\n");
    printf("content in buffer");
    _exit(0);//直接清空缓存空间,可能造成数据损失,不善后处理;
}

运行结果:

此时可以看出,_exit(0)函数直接退出清空数据,硬退出,而没有管缓冲区的数据,也没有写会文件或者对缓冲区的数据做善后处理,只输出了一句,第二句的数据丢失了,相反exit(0)则会对缓冲区的数据进行处理后终止,例如写会文件,打印等等一些后续。

时间: 2024-10-01 03:39:34

linux下exit()和_exit()区别的相关文章

linux 下 /bin /sbin 的区别 -- (转)

/bin,/sbin,/usr/bin,/usr/sbin区别 /  : this is root directory                root 用户根目录 /bin : commands in this dir are all system installed user commands    系统的一些指令 /sbin:  commands in this dir are all system installed super user commands  超级用户指令 系统管理

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的源码中

Unix / Linux 下 nohup 和 &amp; 的区别

声明:本文首发 简单教程,网址为 https://www.twle.cn/t/332#reply0 就在刚刚回家的路上,被前同事夺命三连 call 呼唤解决一个问题:为啥放在 crontab 里的命令放在 Shell 会进入假死状态? 那我就问了?什么是假死状态? 同事说,就是一直不会执行完毕,占着 Shell,不能做其它事情. 多次沟通后,才知道他写的这个是一个守护进程似的死循环程序,一旦启动除非发生意外,否则不会自己退出. 那肯定,很显然,会占着 Shell 啊. nohup 和 & 我给的

Linux下关机命令的区别 (halt,poweroff,reboot,shutdown,init)

在Linux下一些常用的关机/重启命令. 1.shutdown shutdown命令安全地将系统关机.    有些用户会使用直接断掉电源的方式来关闭linux,这是十分危险的.因为linux与windows不同,其后台运行着许多进程,所以强制关机可能会导致进程的数据丢失﹐使系统处于不稳定的状态﹐甚至在有的系统中会损坏硬件设备.而在系统关机前使用shutdown命令﹐系统管理员会通知所有登录的用户系统将要关闭.并且login指令会被冻结﹐即新的用户不能再登录.直接关机或者延迟一定的时间才关机都是可

标准c库函数与Linux下系统函数库 区别 (即带不带缓冲区的学习)

我们都知道,C语言在UNIX/Linux系统下有一套系统调用(系统函数),比如文件操作open().close().write().read()等,而标准C语言的库函数中也有一套对文件的操作函数fopen().fclose().fwrite().fread()等..那么同样是对文件的操作函数,标C与UC有什么区别呢?是标C效率高还是UC效率高呢?今天就让我们来一探究竟. 程序作用:将0~999999这1000000个整型数据写入文件. 1.标准C实现大量数据写入文件: /*文件名test1.c*

linux下 bash_profile和bashrc区别

[.bash_profile 与 .bashrc 的区别].bash_profile is executed for login shells, while .bashrc is executed for interactive non-login shells. [login shell 与 non-login shell 的区别]1.当你直接在机器login界面登陆.使用ssh登陆或者su切换用户登陆时,.bash_profile 会被调用来初始化shell环境Note:.bash_prof

linux 下 /bin /sbin 的区别

/bin,/sbin,/usr/bin,/usr/sbin区别 /  : this is root directory                root 用户根目录 /bin : commands in this dir are all system installed user commands    系统的一些指令 /sbin:  commands in this dir are all system installed super user commands  超级用户指令 系统管理

(转)Linux下数据段的区别(数据段、代码段、堆栈段、BSS段)

进程(执行的程序)会占用一定数量的内存,它或是用来存放从磁盘载入的程序代码,或是存放取自用户输入的数据等等.不过进程对这些内存的管理方式因内存用途 不一而不尽相同,有些内存是事先静态分配和统一回收的,而有些却是按需要动态分配和回收的.对任何一个普通进程来讲,它都会涉及到5种不同的数据段. Linux进程的五个段 下面我们来简单归纳一下进程对应的内存空间中所包含的5种不同的数据区都是干什么的. BSS段:BSS段(bss segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域.BS

Mysql在windows下和linux下对表名大小写默认要求的一个细节

今天在虚拟机里搭建项目环境,偷了下懒,直接把本机数据库中的表用sqlyog复制给虚拟机中的数据库,然后开始部署项目,项目一启动提示: Table 'sdmqrt.QRTZ_LOCKS' doesn't exist 我一看,找不到表,奇怪啊,我本机的数据库不可能少表啊,检查一遍虚拟机中的表也的确存在..这问题巧就巧在是qrtz_locks表,也就是调度任务表,spring quartz恰巧有那么一个bug,然后我整个人就掉进那个bug里面去了,不清楚这个bug的可以直接百度. 按照那个bug的处理