lienhua34
2014-10-02

1 进程的终止方式

进程的终止方式有 8 种,其中 5 种为正常终止,它们是

1. 从 main 返回。

2. 调用 exit。

3. 调用_exit 或_Exit。

4. 最后一个线程从其启动例程返回。

5. 最后一个线程调用pthread_exit。

另外三种为异常终止方式,它们是

1. 调用 abort。

2. 接到一个信号并终止。

3. 最后一个线程对取消请求做出响应。

2 exit 函数

有三个函数用于正常终止一个程序:_exit 和_Exit 立即进入内核,exit 则先执行一些清理处理(包括调用执行各终止处理程序,关闭所有标准 I/O 流等),然后进入内核。

#include <stdlib.h>

void exit(int status);

void _Exit(int status);

#include <unistd.h>

void _exit(int status);

三个 exit 函数都带一个整型参数,称之为终止状态(或退出状态,exit status)。main 函数返回一个整型值与用该值调用 exit 是等价的,即 exit(0)等价于 return(0)。

如果(a)main 执行了一个无返回值的 return 语句,或(b)main 没有声明返回类型为整型,则该进程的终止状态是未定义的。若 main 函数的返回类型是整型,并且 main 执行到最后一条语句时隐形返回(没有显示使用 return 或者调用 exit 函数),历史版本的终止状态是未定义的,而 ISOc 标准 1999 规定该进程的终止状态为 0.

3 终止处理程序

前面一节讲到调用 exit 函数,在进入内核之前,进程会调用一些终止处理程序(exit handler)。我们可以通过调用 atexit 函数注册终止处理程序。按照 ISO C 的规定,一个进程可以注册多达 32 个终止处理函数。

#include <stdlib.h>

int atexit(void (*func)(void));

返回值:若成功则返回0,若出错则返回非0值。

atexit 的参数是一个函数地址,注册的函数没有参数也没有返回值。exit 调用这些函数的顺序与它们注册时候的顺序相反。同一个函数如果被注册多次,则也会被调用多次。

例子:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
static void my_exit1(void);
static void my_exit2(void);
int
main(void)
{
if (atexit(my_exit2) != ) {
printf("can't register my_exit2: %s\n", strerror(errno));
}
if (atexit(my_exit1) != ) {
printf("can't register my_exit1: %s\n", strerror(errno));
}
if (atexit(my_exit1) != ) {
printf("can't register my_exit1: %s\n", strerror(errno));
}
printf("main is done\n");
exit();
}
static void
my_exit1(void)
{
printf("first exit handler\n");
}
static void
my_exit2(void)
{
printf("second exit handler\n");
}

编译该程序,生成 atexitdemo 文件,然后执行该文件,

lienhua34:demo$ gcc -o atexitdemo atexitdemo.c
lienhua34:demo$ ./atexitdemo
main is done
first exit handler
first exit handler
second exit handler

(done)

UNIX环境编程学习笔记(15)——进程管理之进程终止的更多相关文章

  1. UNIX环境编程学习笔记(21)——进程管理之获取进程终止状态的 wait 和 waitpid 函数

    lienhua342014-10-12 当一个进程正常或者异常终止时,内核就向其父进程发送 SIGCHLD信号.父进程可以选择忽略该信号,或者提供一个该信号发生时即被调用的函数(信号处理程序).对于这 ...

  2. UNIX环境编程学习笔记(19)——进程管理之fork 函数的深入学习

    lienhua342014-10-07 在“进程控制三部曲”中,我们学习到了 fork 是三部曲的第一部,用于创建一个新进程.但是关于 fork 的更深入的一些的东西我们还没有涉及到,例如,fork ...

  3. UNIX环境编程学习笔记(18)——进程管理之进程控制三部曲

    lienhua342014-10-05 1 进程控制三部曲概述 UNIX 系统提供了 fork.exec.exit 和 wait 等基本的进程控制原语.通过这些进程控制原语,我们即可完成对进程创建.执 ...

  4. UNIX环境编程学习笔记(17)——进程管理之进程的几个基本概念

    lienhua342014-10-05 1 main 函数是如何被调用的? 在编译 C 程序时,C 编译器调用链接器在生成的目标可执行程序文件中,设置一个特殊的启动例程为程序的起始地址.当内核执行 C ...

  5. UNIX环境编程学习笔记(24)——信号处理进阶学习之信号集和进程信号屏蔽字

    lienhua342014-11-03 1 信号传递过程 信号源为目标进程产生了一个信号,然后由内核来决定是否要将该信号传递给目标进程.从信号产生到传递给目标进程的流程图如图 1 所示, 图 1: 信 ...

  6. UNIX环境编程学习笔记(26)——多线程编程(一):创建和终止线程

    lienhua342014-11-08 在进程控制三部曲中我们学习了进程的创建.终止以及获取终止状态等的进程控制原语.线程的控制与进程的控制有相似之处,在表 1中我们列出了进程和线程相对应的控制原语. ...

  7. UNIX环境编程学习笔记(23)——信号处理初步学习

    lienhua342014-10-29 1 信号的概念 维基百科中关于信号的描述是这样的: 在计算机科学中,信号(英语:Signals)是 Unix.类 Unix 以及其他 POSIX 兼容的操作系统 ...

  8. UNIX环境编程学习笔记(9)——文件I/O之文件访问权限的屏蔽和更改

    lienhua342014-09-10 1 文件访问权限 在文件访问权限和进程访问控制中,我们已经讲述过文件访问权限位,为了方便,我们重新列在下面, 表 1: 文件的 9 个访问权限位  st_mod ...

  9. UNIX环境编程学习笔记(3)——文件I/O之内核 I/O 数据结构

    lienhua342014-08-27 内核使用三种数据结构表示打开的文件,分别是文件描述符表.文件表和 V 节点表. (1) 每个进程在进程表中都有一个记录项,记录项中包含有一张打开文件描述符表,每 ...

随机推荐

  1. QT-提示“database not open”

    问题现象: 要用QT开发"SQLite"时出现如下提示: QSqlQuery::exec: database not open QSqlDatabase: QSQLITE driv ...

  2. ios 两个 TableView 之间的联动, TableView 与 CollectionView 之间的联动

    两个 TableView 之间的联动, TableView 与 CollectionView 之间的联动 这是一个创建于 359 天前的主题,其中的信息可能已经有所发展或是发生改变. [联动] :两个 ...

  3. 基于jQuery适合做图片类网站的特效

    分享一款基于jquery适合做图片类网站的特效.这是一款鼠标经过图片滑动弹出标题效果代码.效果图如下: 在线预览   源码下载 实现的代码. html代码: <div class="c ...

  4. golang包管理的取巧

    常见的golang的包管理工具 glide 使用yaml做配置,语义化版本管理,可以设置镜像,下载x系列库,但是x系列库被第三方库依赖时会出现下载失败. dep 亲儿子,语义化版本管理,无法解决墙 v ...

  5. 纯真ip导入mysql

    先从纯真官网右侧下载ip数据库 更新后,点击解压,可以把数据库保存为txt格式 格式化数据 ip格式如下图 可见并不是很规范,而且最底部字段数也不一致 先用正则表达式,查找替换一下 (\d+.\d+. ...

  6. WebSphere ILOG JRules 规则引擎运行模式简介

    WebSphere ILOG JRules 规则引擎运行模式简介 引言 作为 JRules 的核心组件,规则引擎决定了在规则集的执行过程中,哪些业务规则会被执行,以及以何种顺序执行.理解并合理选择规则 ...

  7. opencv 中affine函数实现旋转和平移

    图像旋转和平移是图像处理中常用的一种操作,opencv2和opencv3中对图像的旋转和平移都是通过仿射变换函数cv::warpAffine()来实现的. 1.图像的旋转 图像的旋转具体实现分为两步: ...

  8. Java 源码赏析 - java.lang - Void

    被人鄙视了,于是也来读读源码... package java.lang; /** * The Void class is an uninstantiable placeholder class to ...

  9. js 日期格式化函数

    直接上代码: // 日期格式化函数 // yyyy/MM/dd hh:mm:ss SSS ⇒ "2017/05/16 09:24:20 850" //"yyyy/M/d ...

  10. idea properties文件unicode码问题

    在git hub上下载了个工程.但是properties文件一直显示不了中文: # \u662F\u5426\u4F7F\u7528\u8FDC\u7A0B\u914D\u7F6E\u6587\u4E ...