《unix高级环境编程》进程环境——进程终止

        当内核执行C程序时(使用一个exec函数执行),在调用mian函数前先调用一个特殊的启动例程。可执行程序文件将此启动例程指定为程序的起始地址。下面是C程序启动和终止的流程,由图中可以知道,进程的终止根据不同的函数调用是不一样的,其中_exit和_Exit函数是终止进程直接进入内核,exit函数则先执行一些清理,然后在进入内核。内核是程序执行的方法只有调用exec函数。虚线框里面表示用户进程。

《unix高级环境编程》进程环境——进程终止_第1张图片

进程终止

       unix中有8种进程终止方式,其中5种是正常终止,3种是异常终止。如下所示:

正常终止:

  1. 从main函数返回。
  2. 调用exit函数。
  3. 调用_exit或_Exit函数。
  4. 最后一个线程从其启动例程返回。
  5. 最后一个线程调用pthread_exit。
异常终止:

  1. 调用abort函数。
  2. 接到一个信号并终止。
  3. 最后一个线程对取消请求做出响应。

exit函数

          下面三个函数都是属于正常终止进程,_exit和_Exit直接进入内核,exit函数需要执行一些清理操作(例如终止处理程序、关闭标准I/O流等操作),然后才进入内核。

/* 正常终止程序函数 */
#include <stdlib.h>

void exit(int status);//进入内核之前执行一些清理操作
void _Exit(int status);//直接进入内核

#include <unistd.h>
void _exit(int status);//直接进入内核
//参数status为终止状态

atexit函数

        exit函数自动调用终止处理程序函数,这些终止处理程序函数由atexit函数进行登记,exit根据atexit登记的顺序,相反顺序的调用终止处理程序函数,同一个函数若登记多次,则exit函数就多次调用该函数。atexit函数的参数是一个函数地址。

#include <stdlib.h>
 int atexit(void (*func)(void));
//返回值:若成功则返回0,若出错则返回非0值

测试exit的执行过程:

#include <stdio.h>
#include <stdlib.h>
#include "apue.h"

static void my_exit1(void);
static void my_exit2(void);
int main(void)
{
    if (atexit(my_exit2) != 0)
        err_sys("can't register my_exit2.\n");
    if (atexit(my_exit1) != 0)
        err_sys("can't register my_exit1.\n");
    if (atexit(my_exit1) != 0)
        err_sys("can't register my_exit1.\n");
    printf("main is done.\n");
    return 0;
}

static void my_exit1(void)
{
    printf("first exit register.\n");
}
static void my_exit2(void)
{
    printf("second exit register.\n");
}

参考资料:

《unix高级环境编程》

你可能感兴趣的:(进程终止,Unix高级环境编程,exit函数)