APUE进程环境小结

   

一.main函数是如何被调用的

       内核执行C程序时,在调用main函数前先会调用一个特殊的启动例程。可执行程序文件将此启动例程指定为程序的起始地址。启动例程从内核取得命令行参数和环境变量值,然后为按上述方式调用 main函数做好安排。

二.进程的八种终止方式

1.     从main返回

2.     调用exit

3.     调用_exit或_Exit

4.     最后一个线程从其启动例程返回

5.     最后一个线程调用pthread_exit

异常终止有三种方式,它们是:

1.     调用abort

2.     接到一个信号并终止

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

上一节提到到的启动例程会使main返回后立即调用exit函数,如果启动例程以C代码形式表示(事实上启动例程是常常使用汇编语言编写),那么它调用main函数的形式就可能是如下:exit(main(argc,argv));

而来看exit函数,

#include<stdlib.h>

void exit(int status); void _Exit(int status);

#include<unistd.h>

void _exit(int status);

三个函数用于正常终止一个程序,其中_exit和_Exit马上进入内核,exit则先执行一些例如调用执行各终止处理程序,关闭所有标准IO流(为所有打开流调用fclose函数)等清理操作然后才进入内核。

三.atexit函数

一个进程可以登记多达32个函数由exit函数自动调用。我们称这些函数为终止处理程序,并调用atexit函数来登记这些函数。

  #include<stdlib.h>

   int atexit(void (*func)void)

  参数是一个函数地址,且调用此函数时无需向它传送任何参数,也不期望返回一个值。调用这些函数的顺序与登记顺序相反。且同一函数登记多次也会被调用多次。

 注:exit执行时,首选调用各终止程序,然后再调用fclose,关闭所有打开流,如果程序调用了exec函数族中任一函数,则将清除所有已安装的终止处理程序。

四.环境表

每个程序都会接收到一张环境表,与参数表一样,环境表也是一个字符指针数组,其中每个指针包含一个以null结束的c字符串的地址。全局变量environ包含了该指针数组的地址

extern char **environ;

因为ISO C和POSIX.1都规定不使用第三个参数,通常用getenv和putenv函数来访问特定的环境变量,而不是environ变量,当然要查看整个环境还是必须使用environ指针。


五.C程序的存储空间布局

正文段(or 代码段),数据段,BSS(Block Started by Symbol,来源于早期汇编运算符)非初始化数据段,栈,堆。。如图


其中,正文段:CPU执行的机器指令部份,通常是正文段可以共享的且通常是只读的(显然,防止程序以外而修改自身指令)。

数据段:包含了程序中需明确地赋初值的变量。

BSS段:程序开始前,内核将此段中的数据初始化为0或空指针。如以下声明:long  sum[100];将会被放于非初始化数据段。

另外,未初始化数据段内容并不放在磁盘上的程序文件中,需要存放的只有正文段和初始化数据段。

  

六.setjmp ,longjmp

这两个函数主要有几点需要注意

可以跨越函数,对于处理发生在深层嵌套函数调用中的出错情况是非常有用的,它在栈上跳过若干调用帧,返回到当前函数调用路径上的某一个函数中。

#include<setjmp.h>

int setjmp(jmp_env);

void longjmp(jmp_buf env,int val);

其中jmp_env是某种形式的数组,其中存放在调用longjmp时能用来恢复栈状态的所有信息。当检查到一个错误时,调用longjmp函数,其中第二个参数是非零值,它将成为从setjmp处返回的值。因为对于一个setjmp可以有多个longjmp,可以根据返回值判断造成返回的longjmp是在哪个函数中。

而在调用longjmp后返回到main函数时存放在存储器中的变量将具有longjmp时的值,而在cpu和浮点寄存器中的变量则恢复为调用setjmp时的值。如果以不带编译器优化对程序进行编译,所有变量都存放在存储器中(会忽略register存储类说明),所有变量都不会回滚。而进行了优化后,自动变量和register变量都存放在寄存器中,volatile变量仍然会存放在存储器中。如果要编写一个使用非局部跳转的可移植程序,则必须使用volatile属性。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值