进程的终止类别及方式

来源:互联网 发布:java web 项目书籍pdf 编辑:程序博客网 时间:2024/06/05 03:06

进程的终止方式

1. 终止类别

  1. 正常终止

    1. 从main函数返回
    2. 调用exit(标准c库函数)
    3. 调用_exit或者_Exit(系统调用)
    4. 最后一个线程从其启动例程(进程)返回
      1. 启动例程会搜集命令行参数给main传参,并搜集环境信息构建环境表给main函数,还会登记进程的终止函数
      2. 在进程的main函数执行前内核会启动
      3. 编译器在编译时会将启动例程编译进可执行文件中
    5. 最后一个线程调用pthread_exit
  2. 异常终止

    1. 调用abort
    2. 接收到一个信号并终止
    3. 最后一个线程对取消请求做处理响应
  3. 进程返回

    1. 通常进程运行成功返回0,否则返回非0
    2. 在shell中可以查看进程的返回值(echo $?)

2. 自定义终止函数

  • atexit函数

    1. 原型:int atexit(void (*function) (void));
    2. 返回:成功返回0,出错返回-1
    3. 功能:向内核登记终止函数
    4. 注意:
      1. 每个启动的进程都默认的登记了一个标准的终止函数
      2. 终止函数在进程终止时释放进程所占用的一些资源
      3. 登记的多个终止函数的执行顺序是以栈的方式进行,即先登记后执行
  • 示例:

    #include <string.h>    #include <stdio.h>    #include <stdlib.h>    #include <fcntl.h>    #include <unistd.h>    //定义进程的终止函数    void term_fun1(void){        printf("first term fucntion\n");    }    void term_fun2(void){        printf("second term fucntion\n");    }    void term_fun3(void){        printf("third term fucntion\n");    }    int main(int argc, char *argv[]){        if(argc < 3){            fprintf(stderr, "usage: %s file [exit|_exit|return]\n", argv[0]);            exit(1);        }        //向内核登记终止函数        atexit(term_fun1);        atexit(term_fun2);        atexit(term_fun3);        FILE *fp = fopen(argv[1], "w");        fprintf(fp, "hello iotek"); //全缓存函数        if(!strcmp(argv[2], "exit")){            exit(0);        }        else if(!strcmp(argv[2], "_exit")){            _exit(0);        }        else if(!strcmp(argv[2], "return")){            return 0;        }        else{            fprintf(stderr, "usage: %s file [exit|_exit|return]\n", argv[0]);        }    }
  • 运行测试

    1. return

      return

      1. 说明:前面说过终止函数的方式是以栈的方式进行,所以看到3,2,1的顺序
    2. exit

      exit

      1. 说明:前面说过终止函数的方式是以栈的方式进行,所以看到3,2,1的顺序,和return不同的是只释放一次资源
    3. _exit(_Exit)

      _exit_

      1. 说明:在调用的时候,因为fprintf是c语言的带缓冲的库函数,所以存放数据是先存放在自己的缓冲区,等待写满,但是在这之前调用_exit函数导致没有清缓存,最终文件里面也没有数据

3. 总结

return exit _exit (_Exit) 是否刷新标准I/O缓存 是 是 否 是否自动调用终止函数 是 是 否

- 注意:在网络编程时,调用return几次,就释放几次内核资源,调用exit多次,只释放一次。