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. spring batch中MyBatisPagingItemReader分页使用介绍

    假如是mysql的话,SQL语句 <![CDATA[select * from ( SELECT so.* FROM t_tm_sales_order so where so.last_modi ...

  2. win7+php5.3.10下安装memcache (转)

    因为升级到了5.3.10,所以之前的dll不能使用了,弄了好久,终于还是在老外的博客上找到了解决方法: (环境是win7+php5.3.10+win32) 1.解压附件memcached到某个目录,本 ...

  3. 【Unity】使用JSONObject解析Json

    为何要用JSONObject 之前已经用过JsonUtility和Newton.Json来解析Json了,为什么现在又要用一个新的JSONObject来解析Json? 使用JsonUtility:ht ...

  4. [Selenium.2.Testing.Tools.Beginners.Guide]读书笔记

    Assert, this allows the test to check if the element is on the page, if it is not available then the ...

  5. linux使用指导-debian/archlinux/LFS

    debian系统参考配置手册:https://www.debian.org/doc/manuals/debian-reference/index.en.html ArchLinux系统参考配置手册:s ...

  6. docker原理

    Docker原理11 Linux Namespace 11 AUFS文件系统17 重新理解Docker的各种命令18 Docker原理 Linux Namespace docker是一个容器引擎,容器 ...

  7. linux系统管理命令(五)

    [教程主题]:1.系统管理命令 [1.1]用户和组管理 在Linux操作系统中,任何文件都归属于某一特定的用户,而任何用户都隶属于至少一个用户组.用户是否有权限对某文件进行访问.读写以及执行,受到系统 ...

  8. Android开发,使用背景图(xml drawable)为view 设置边框

    Android 开发中,遇到需要设置边框的情景,使用背景图来实现,代码如下: <layer-list xmlns:android="http://schemas.android.com ...

  9. Redis管道传输

    Redis是一个TCP服务器,并支持请求/响应协议.redis的一个请求完成需要下面的步骤: 客户端发送一个查询到服务器,并从套接字中读取,通常在封闭的方式,对服务器的响应. 服务器处理命令并将响应返 ...

  10. git push报错:error: RPC failed; result=22, HTTP code = 413

    新项目推送到服务器时报错: error: RPC failed; result=22, HTTP code = 413| 7.66 MiB/s    fatal: The remote end hun ...