return是返回的最常用的方式

_exit属于POSIX定义的系统调用

exit是GLIBC封装之后的函数

1 _exit和exit都会导致整个进程退出,清理进程所占用的资源,但是glibc封装exit函数的时候加了一些功能:比如提供了在结束程序时回调的接口(atexit), flush 缓冲区(系统调用是没法做这个的

,因为像printf, scanf之类的缓冲区都属于应用层缓冲区,内核清理资源自然无法顾及)

2return 会清理函数栈,另外两个就不会了,如果是最后一个线程return,也会像exit那样清理资源并flush缓冲区,这一点可以通过一段代码观察一下:

  

 #include<iostream>
#include<unistd.h>
using namespace std; class A
{
public:
A(){
cout << "constructor" << endl;
}
~A(){
cout << "distructor" << endl;
}
};
void func(int i)
{
A a;
if(i == )
_exit(-);
else
return;
} int main()
{
func();
return ;
}

这里可以发现,只有按照return 方式返回局部变量a的析构函数才能得到调用,因为exit _exit都是不清理函数栈的.

一般这不会有什么问题,因为资源都回收了,栈空间自然也没了.但是对于约定在函数返回时调用的函数就没法调用了.

还有一点要注意的是,全局变量并不在栈空间里面,对于C++的情形而言,可以在全局变量的构造函数中申请资源然后

在程序结束的时候由析构函数释放.这个过程事实上是通过在函数启动的时候插入全局变量的构造函数,函数退出的地方插入

析构函数做到的.所以,即使是调用exit,全局变量仍旧可以正常析构. 但是_exit就不一样了,仍旧不会释放(_exit属于系统

调用,它只管内核空间中的一些资源释放)

#include<iostream>
#include<unistd.h>
using namespace std; class A
{
public:
A(){
cout << "constructor" << endl;
}
~A(){
cout << "distructor" << endl;
}
};
void func(int i)
{
A a;
if(i == )
_exit(-);
else
return;
}
A ta;
int main()
{
A a;
_exit();
}

3关于vfork的问题

#include<unistd.h>
#include<stdio.h>
int glovalvar = ; int main()
{
int var = ;
pid_t pid;
printf("before vfork\n");
if((pid = vfork()) < )
{
fprintf(stderr, "vfork error");
return ;
}
else if(pid == )
{
glovalvar++;
var++;
_exit();
}
else
{ }
printf("pid = %ld, glob=%d, var=%d\n", (long)getpid(), glovalvar, var);
return ;
}

这是apue上面的一段示例代码,很惊奇的发现居然可以在子进程中访问到局部变量var,这意味着什么??要知道单一进程内
,如果出现函数调用,过程是这样的:

1返回地址压栈

2参数压栈

3保存当前的ebp

在程序中写一个return意味着什么???思考一下,其实是要清理当前的函数栈的,C语言的情形下比较好想,反正栈指针退到指定位置就好

c++中却还要在返回之前调用局部变量的析构函数

最最重要的是,即使是像c语言那样简单的将栈指针回退,在vfork的情形下,也会出问题:

回退到哪??前面已经说过了,返回地址处(也就是当前函数的调用点)!

可以想象,这里所说的在父进程空间运行多么图省事,连一个单独的函数调用的开销都不肯付出(如果有子过程调用,那局部变量不可能访问得到)

直接就用了父进程main函数的函数栈, 你一个return,它直接把栈指针指到了main函数调用点,简单来说,就是main函数的函数栈被清理了,那切换到父进程就莫名奇妙了!

而如果是exit或_exit,则进程直接退出了,对于用户空间的函数栈根本不理会(具体来说就是ebp, esp寄存器的值)

所以不会出现问题.

return, exit, _exit的区别的更多相关文章

  1. return exit _exit

    (1)进程终止: C程序的终止分为两种:正常终止和异常终止. 正常终止分为: return, exit, _exit, _Exit, pthreade_exit. 异常中指分为: abort, SIG ...

  2. PHP中return,exit,die的区别

    参考:die(),exit(),return的区别 1.die() 是遇到错误才停止,停止程序运行,输出内容(是程序级别的) 2.exit,exit():是一个函数 是停止程序运行,前者不输出内容:后 ...

  3. exit() _exit() 函数区别

    exit(): --stdlib.h (1) 所有使用atexit()注册的函数,将会被以注册相反的顺序调用: (2) 所有打开的输出流被刷新,并且关闭流: (3) 使用tmpfile()创建的文件将 ...

  4. Linux中exit与_exit的区别

    在exit,_exit的区别 - exit()与_exit()函数的区别(Linux系统中)2012-03-20 15:19:53 分类: LINUX 注:exit()就是退出,传入的参数是程序退出时 ...

  5. 引用 exit、return、_exit、_Exit这几个函数的区别

    引用 exit.return._exit._Exit这几个函数的区别 一.exit函数和return函数的主要区别是: exit用于在程序运行的过程中随时结束程序,其参数是返回给OS的.也可以这么讲: ...

  6. exit和_exit的区别

    参考 http://www.cnblogs.com/hnrainll/archive/2011/08/17/2142001.html p.p1 { margin: 0.0px 0.0px 0.0px ...

  7. fork-vfork -exit&_exit

    昨天帮人查bug,发现了一个vfork fork exit  _exit不分导致的问题. 使用vfork 后调用exit导致的问题. 主要需要弄清楚他们之间的区别: 1.  fork  ():子进程拷 ...

  8. return和break的区别

    /* Name:return和break的区别 Copyright: By.不懂网络 Author: Yangbin Date:2014年2月25日 02:13:22 Description:以下代码 ...

  9. java中,return和return null有什么区别吗?

    java中,return和return null有什么区别吗? 最大的区别:return;方法的返回值必须是void!return null;方法的返回值必须不是 原始数据类型(封装类除过)和void ...

随机推荐

  1. English substitute

    英语写作中替换掉用到发腻的↓常用词↓,吐血整理2小时~~   动词替换:   1.Improve 提高:   Promote: 促进AC之间的贸易 promote the trade between ...

  2. is(C# 参考)

    检查对象是否与给定类型兼容. 例如,下面的代码可以确定对象是否为 MyObject 类型的一个实例,或者对象是否为从 MyObject 派生的一个类型:     if (obj is MyObject ...

  3. 空心文字闪动--css3

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...

  4. python 使用*args 和**kwargs

    def fun_var_args(farg, *args): print "arg:", farg for value in args: print "another a ...

  5. 關於my97datepicker

    原因的一篇是比較老的版本了 目前使用4.72 目前碰到一種情況就是使用了PopUpForm.js,也就是在頁面中彈出一個框,用來編輯,或者添加數據等功能. 使用知道時間會出現一種情況.時間顯示被ifr ...

  6. 实验一 Java开发环境的熟悉境的熟悉

    - 运行结果: (一)命令行下Java程序开发 (二)Eclipse下Java程序开发.调试 设置断点和单步运行 单步运行:Step Into(快捷捷F5)和Step Over(快捷捷F5) 使程序直 ...

  7. JDicom使用指南

    适用条件本指南用于使用JDicom进行环境模拟.产品调试. 一.安装JDicom运行JDicom安装程序之前,需安装JRE 1.3及以上版本.否则,弹出如下图所示报错 安装JRE 1.4:双击运行可执 ...

  8. 深入理解Redis:底层数据结构

    简介 redis[1]是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合).zset(sorte ...

  9. [js]变量声明、函数声明、函数定义式、形参之间的执行顺序

    一.当函数声明和函数定义式(变量赋值)同名时 function ledi(){ alert('ledi1'); }; ledi(); var ledi = function (){ alert('le ...

  10. [css]邮件的写法

    <style type="text/css">        /* Client-specific Styles */        #outlook a{paddin ...