进程的启动和终止

C程序的启动过程

        我们通常认为C语言的起始函数是main函数,实际上一个程序的启动函数不一定是main函数,这个可以采用链接器来设置,但是gcc中默认main函数就是C语言的入口函数,在执行main函数之前,内核会启动一个特殊例程

        这个特殊例程的作用:

  • 搜集命令行的参数传递给main函数中的argc和argv;
  • 搜集环境信息构建环境表并传递给main函数;
  • 登记进程的终止函数
        因此,对于程序来说,main函数并不是起始的,但是对C语言而言,main函数就是入口地址,其他的链接器帮助我们完成,实际上main函数的执行时使用了exec函数,这是一个函数族,这也是一个内核执行一个程序的唯一方法,这在进程控制部分将进行分析。


进程终止函数atexit()

        #include <stdlib.h>

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

        返回:成功返回0,出错返回-1;

        功能:注册终止函数(即main执行结束后调用的函数,当程序通过调用exit()或从main中返回时,参数function指定的函数会先被                     调用,然后才真正由exit()结束程序)

  • 每个启动的进程都默认登记了一个标准的终止函数;
  • 终止函数在进程终止时释放进程所占用的一些资源;
  • 登记的多个终止函数执行顺序是以栈的方式执行,先登记的后执行;
        按照ISO C的规定,一个进程可以登记多达32个函数,这些函数将由exit自动调用。atexit()注册的函数类型应为不接收任何参数的void函数,exit调用这些注册函数的顺序与他们登记时候的顺序相反。同一个函数如若多次登记,则也会被多次调用。


进程终止方式

    a.正常终止

  • 从main函数返回;
  • 调用exit(标准c库函数);
  • 调用_exit或_Exit(系统调用)
    b.异常终止

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

  • 通常程序运行成功返回0,失败返回非0;
  • 在shell中可以查看进程返回值(echo $?);


一个问题:main函数退出之后,是否还可以执行程序?

        #include 

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

        其中,atexit的参数是一个地址,当调用此函数时无需传递任何参数,该函数也无返回值,atexit函数称为终止处理程序注册程序,注册完成以后,当函数终止时,exit()函数会主动调用前面的各个函数。由于exit是在main函数调用结束以后调用,所以这些函数的执行肯定在main函数之后。这就是上面问题的答案。即采用atexit函数登记相关的执行函数即可。

        简单的示例:

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

void func1(void)
{
      printf("in func1\n");
}
void func2(void)
{
      printf("in func2\n");
}
void func3(void)
{
      printf("in func3\n");
}

int main(void)
{
      atexit(func1);
      atexit(func2);
      atexit(func3);

      printf("I'm main\n");
      
      exit(0);
      //return 0;
}
具体执行结果如下所示:



        根据exit的执行过程可知,exit首先会调用各个终止处理程序,然后按需多次调用close(),关闭所有打开流,也就是说exit函数会执行一个标准库的清理关闭操作,对所有打开的流调用fclose(),这样就会造成所有缓冲的输出数据都被冲洗写入文件中。


        注意:在终止方式方式中,调用_exit,_Exit都不会调用终止程序,异常终止也不会。

        如果将上述程序中最后的exit(0)改为_exit(0)或_Exit(0),执行结果如下:


        也就是说根本不会执行到最开始注册的函数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值