exit()’与‘_exit()’

#define __NR_exit                 1
#define __NR__exit __NR_exit /* 摘自文件include/asm-i386/unistd.h*/
   "__NR_"是在Linux的源码中为每个系统调用加上的前缀,请注意第一个exit前有2条下划线,第二个exit前只有1条下划线。
Linux核心还提供了一些C语言函数库,这些库对系统调用进行了一些包装和扩展,因为这些库函数与系统调用的关系非常紧密,所以习惯上把这些函数也称为系统-调用。#define这句只能说明内核里的两个系统调用_exit和exit相同,但其封装后对应的C库函数_exit()和exit()是不同的。
   exit()函数定义在stdlib.h中,而_exit()定义在unistd.h中。
   _exit()函数的作用最为简单:直接使进程停止运行,清除其使用的内存空间,并销毁其在内核中的各种数据结构;exit()函数则在这些基础上作了一些包装-,在执行退出之前加了若干道工序,也是因为这个原因,有些人认为exit已经不能算是纯粹的系统调用。
   exit()函数与_exit()函数最大的区别就在于exit()函数在调用exit系统调用之前要检查文件的打开情况,把文件缓冲区中的内容写回文件,即所谓的"清理I/O缓冲"。
   ‘exit()’与‘_exit()’有不少区别在使用‘fork()’,特别是‘vfork()’时变得很突出。
   ‘exit()’与‘_exit()’的基本区别在于前一个调用与实施库里用户状态结构(user-mode constructs)有关的清除工作(clean-up),而且调用用户自定义的清除程序 (译者注:自定义清除程序由atexit函数定义,可定义多次,并以倒序执行),相对 应,后一个函数只为进程实施内核清除工作。
   在由‘fork()’创建的子进程分支里,正常情况下使用‘exit()’是不正确的,这是因为使用它会导致标准输入输出(译者注:stdio: Standard Input Output)的缓冲区被清空两次,而且临时文件被出乎意料的删除(译者注:临时文件由tmpfile函数创建在系统临时目录下,文件名由系统随机生成)。在C++程序中情况会更糟,因为静态目标(static objects)的析构函数(destructors)可以被错误地执行。(还有一些特殊情况,比如守护程序,它们的父进程需要调用‘_exit()’而不是子进程;适用于绝大多数情况的基本规则是,‘exit()’在每一次进入‘main’函数后只调用一次。)
   在由‘vfork()’创建的子进程分支里,‘exit()’的使用将更加危险,因为它将影响父进程的状态。

vfork与fork的区别
  vfork与fork主要有三点区别:
  .fork():子进程拷贝父进程的数据段,堆栈段
  vfork():子进程与父进程共享数据段
  .fork()父子进程的执行次序不确定vfork 保证子进程先运行,在调用 exec 或 exit 之前与父进程数据是共享的,在它调用 exec或 exit 之后父进程才可能被调度运行。
  .vfork()保证子进程先运行,在它调用 exec 或 exit 之后父进程才可能被调度运行.如果在调用这两个函数之前子进程依赖于父进程的进一步动作,则会导致死锁。

#include <stdlib.h>
函数名: abort

功 能: 异常终止一个进程

用 法: void abort(void);

abort()是使异常程序终止,同时发送SIGABRT信号给调用进程。

程序例:

#include  <stdio.h>
#include  <stdlib.h>
void main( void )
{
   FILE *stream;
   if( (stream = fopen( "NOSUCHF.ILE", "r" )) == NULL )
   {
      perror( "Couldn't open file" );
      abort();
   }
   else
      fclose( stream );
}

输出:
Couldn't open file: No such file or directory
abnormal program termination

猜你喜欢

转载自aircoder.iteye.com/blog/1841305