zoukankan      html  css  js  c++  java
  • 第5章 进程环境(2)_进程的启动和终止

    2. 进程启动和终止

    2.1 C程序启动过程

    (1)启动例程

      ①是一段程序代码,放置在/lib/libc.so.***中。编译器在编译时会将启动例程的代码编译进可执行文件中

      ②可执行程序将这段嵌入的启动例代码指代为程序的起始地址

      ③当内核执行C程序时(使用exec函数),在调用main前先执行启动例程代码

    (2)启动例程的作用

      ①搜集命令行的参数传递给main函数中的argc和argv

      ②搜集环境信息构建环境表并传递给main函数

      ③登记进程的终止函数

    2.2 进程终止

     

    进程终止

    主要方式

    正常终止

    ①从main函数返回;②调用exit(标准C库函数);

    ③调用_exit或_Exit(系统调用);

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

    ⑤最后一个线程调用pthread_exit

    异常终止

    ①调用abort;②接到一个信号并终止;

    ③最后一个线程对取消请求做出响应

    进程返回

    ①通常程序运行成功返回0,否则返回非0。②在shell中可以通过echo $?查看进程返回值

    2.3 相关函数

    (1)exit函数

    头文件

    #include<stdlib.h>

    函数

    void exit(int status);  

    void _Exit(int status);

    void _exit(int status); //#include <unistd.h>

    功能

    终止进程

    备注

    (1)_exit和_Exit立即进入内核

    (2)exit会先执行一些清理处理(包括调用执行各终止处理程序,关闭所有标准I/O流等),然后再进入内核

    (2)atexit函数

    头文件

    #include<stdlib.h>

    函数

    int atexit(void(*function)(void));

    返回值

    若成功则为0,若出错则为-1

    功能

    向内核登记终止处理程序(exit handler)

    备注

    (1)每个启动的进程都默认登记了一个标准的终止函数。

    (2)终止函数在进程终止时释放进程所占用的一些资源。

    (3)登记的多个终止函数执行顺序以栈的方式执行的,即先登记的后执行

    【编程实验】终止处理函数

    //process_term.c

    #include <unistd.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    //定义进程的终止函数
    void term_fun1(void)
    {
        printf("first term function
    ");
    }
    
    void term_fun2(void)
    {
        printf("second term funciton
    ");
    }
    
    void term_fun3(void)
    {
        printf("third term function
    ");
    }
    
    int main(int argc, char* argv[])
    {
        if(argc < 3){
            fprintf(stderr, "usage: %s file [exit|_exit|return]
    ");
            exit(1);
        }    
    
        //调用atexit函数向内核登记终止函数
        //注意:注册终止函数的顺序为func1->fun2->fun3,函数被调用顺序fun3->fun2->fun1
        atexit(term_fun1);
        atexit(term_fun2);
        atexit(term_fun3);
    
        FILE* fp = fopen(argv[1], "w");
        fprintf(fp, "hello world!
    "); //fprintf带缓存,调用exit或return时会被
                                       //流会被关闭,即会被写入指定的文件中。
    
    
        if(!strcmp(argv[2], "exit")){
            exit(0);   //标准C的库函数
        }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]
    ", argv[0]);
        }
    
        return 0;
    }
    /*输出结果:
    [root@localhost 5.process]# bin/process_term term.txt return  //正常退出(调用终止函数和刷新缓存)
    third term function
    second term funciton
    first term function
    [root@localhost 5.process]# cat term.txt
    hello world!
    [root@localhost 5.process]# bin/process_term term.txt exit   //正常退出(调用终止函数和刷新缓存)
    third term function
    second term funciton
    first term function
    [root@localhost 5.process]# cat term.txt
    hello world!
    [root@localhost 5.process]# bin/process_term term.txt _exit //异常退出(不调用终止函数和刷新缓存)
    [root@localhost 5.process]# cat term.txt
    [root@localhost 5.process]# bin/process_term term.txt quit
    usage: bin/process_term file [exit|_exit|return]
    third term function
    second term funciton
    first term function
    [root@localhost 5.process]# cat term.txt
    hello world!
    [root@localhost 5.process]# 
     */

    2.4 C程序的启动和终止

    (1)进程的终止

     

    (2)终止方式的区别

     

    return

    exit()

    _exit/_Exit

    是否刷 新标准I/O缓存

    是否自动调用终止函数

    (3)说明

      ①exit首先调用各终止处理程序然后按需要多次调用fclose关闭所有打开流。而调用_exit或_Exit则将直接进入内核,不会调用终止处理函数和关闭被打开的流。

      ②POSIX标准规定,如果程序调用exec函数族中的任一个函数,则将清除所有己安装的终止处理程序。

      ③内核使程序执行的唯一方法是调用一个exec函数。进程自愿终止的唯一方未能是显式或隐式地(通过调用exit)来调用_exit或_Exit。进程序也可以非自愿地由一个信号使其终止。

  • 相关阅读:
    对类对象使用new时地址分配的情况
    c++堆与栈的简单认识
    多态公有继承
    Cookie & Session & JSP入门
    Response & ServletContext
    Java网络编程篇文章阅读顺序
    URL编程
    UDP网络编程
    TCP网络编程
    InetAddress类的使用
  • 原文地址:https://www.cnblogs.com/5iedu/p/6353938.html
Copyright © 2011-2022 走看看