unix进程的环境--unix环境高级编程读书笔记

     1.进程的启动

     进程总是从   main   函数开始执行的,main函数的函数原型如下:

int main(int argc,char* argv[]);

当内核启动  c   程序时,使用一个   exec   函数。这个   exec   函数就是调用   main   函数之前的一个启动例程。可执行程序文件,将此启动例程的地址设置为程序的起始地址,这个工作是由连接编辑程序(即编译器)设定的,这个连接编辑程序在   linux   中就是gcc啦。启动例程从内核获取命令行参数和环境变量,然后调用   main   函数。

     2.进程的终止

     进程的终止方式分为正常终止和异常终止两种方式,这两种方式的情况如下:

正常终止
1.从   main   函数返回
2.调用   exit   函数
3.调用   _exit   函数

异常终止
1.调用   abort   函数
2.由一个信号终止
     exit   函数和   _exit   函数用来终止一个程序,它们两个的区别是,调用   _exit   函数会立即进入到内核,而调用   exit   函数,会先进行一些处理善后工作(如刷新IO),然后调用   _exit   函数进入内核。我们可以使用   atexit   函数来注册一些终止处理程序,这些终止处理程序在调用   exit   函数时会自动执行,并且先注册的后执行,后注册的先执行。一个c程序的启动和终止的生命周期图如下:


c   语言的命令行参数,我只前曾经总结过,详情参考我的另一篇博客点击打开链接

     3.  c程序的存储空间布局

     由于历史的原因,c程序的存储空间布局一直是如下的格式:

我们就从下到上一次介绍每一个部分。

     正文部分也就是程序体,一般将它设置为只读的,所以程序的正文是可以被几个进程共享的。即使对于经常使用的程序,它的程序正文在内存中也只有一个拷贝。初始化数据段用来存储被赋予初值的全局变量。例如在所有函数之外声明的变量, int max = 100;就存放在这个区域。未初始化数据段用来存储未赋予初值的全局变量。例如,函数之外的声明,long sum[1000];就存储在这个区域中,在这个区域中的值被初始化为0。堆用来为程序在运行时动态的分配内存空间。栈用来存储函数中的一些局部变量以及在发生函数调用时,保存现场信息。最上面用来存放命令行参数和环境变量。

     说到环境变量就需要提到进程的环境表。以前   main   函数的原型是下面这个样子的:

int main(int argc,char* argv[],char* envp[]);

第三个参数是传递的环境表。但是,后来又添加了一个全局变量用来存储环境变量,这个变量就是   environ   ,它是一个存储环境表变量指针的数组,并且最后一个元素是NULL。后来发现   envp   参数并不比   environ   简便。所以,后来的c标准将第三个参数去掉了。但是对于环境变量的存取有几个函数可以使用:
       #include <stdlib.h>

       char *getenv(const char *name);

       #include <stdlib.h>

       int putenv(char *string)

       #include <stdlib.h>

       int setenv(const char *name, const char *value, int overwrite);

       int unsetenv(const char *name);


     4.存储器分配

     存储器分配主要涉及到4个函数:

       #include <stdlib.h>

       void *malloc(size_t size);
       void free(void *ptr);
       void *calloc(size_t nmemb, size_t size);
       void *realloc(void *ptr, size_t size);

这里的函数分配的存储空间主要是在进程的堆上进行的。malloc   函数用来分配一定长度的字节,calloc   函数用来为某一对象分配一定个数的空间,realloc   用来重新调整已分配的动态内存的大小,free   函数用来释放已经分配的内存的空间。

     5.setjmp和longjmp

     setjmp和longjmp函数用来在各个函数之间来回跳转,相当与是函数之间的goto语句。但是在哥各个函数之间跳转时,需要注意变量是否回滚。一般来说,需要将变量声明为   volatile 为最好,这样就可以保证变量不会因为   longjmp   而发生回滚。volatile   为易失性变量,这样就保证了,变量一直存储在存储器中,从而变量就不会发生变化。

     6.共享库

     共享库就是把程序可能用到的头文件,放入到内存的一个共享存储区中,而不用放到每一个程序文件中。当程序执行时,再动态的链接共享存储区中的内容。这样就减少了程序正文的长度,但是也相应的加长了程序的执行时间。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值