Linux系统编程 04 UNIX进程的环境.doc
文本预览下载声明
Linux系统编程 04 UNIX进程的环境
主要内容:当执行程序时,其main函数是如何被调用的,命令行参数是如何传送给执行程序的;典型的存储器布局是什么样式;如何分配另外的存储空间;进程如何使用环境变量;进程终止的不同方式等。
一.main函数C程序总是从main函数开始执行。main函数的原型是:
int main(int argc,char*argv[]);
其中,argc是命令行参数的数目,argv是指向参数的各个指针所构成的数组
当内核起动C程序时(使用一个exec函数),在调用main前先调用一个特殊的起动例程。可执行程序文件将此起动例程指定为程序的起始地址--这是由连接编辑程序设置的,而连接编辑程序则由C编译程序(通常是cc)调用。起动例程从内核取得命令行参数和环境变量值,然后为调用main函数作好安排。内核使程序执行的唯一方法是调用一个exec函数。进程自愿终止的唯一方法是显式或隐式地(调用exit)调用_exit。
(1)命令行参数
当执行一个程序时,调用exec的进程可将命令行参数传递给该新程序
实例
程序7-2将其所有命令行参数都回送到标准输出上,编译此程序,并将其可执行代码文件定名为echoarg,则:
(2)环境表
每个程序都接收到一张环境表。与参数表一样,环境表也是一个字符指针数组,其中每个指针包含一个以null结束的字符串的地址。全局变量environ则包含了该指针数组的地址。
extern char*environ;
例如:如果该环境包含五个字符串,那么它看起来可能如图中所示
环境变量形式是:
name=value ANSI C定义了一个函数getenv,可以用其取环境变量值
#include stdlib.h char*getenv(const char*name);
返回:指向与name关联的value的指针,若未找到则为NULL
注意,此函数返回一个指针,它指向name=value字符串中的value。
二.进程终止(1)有五种方式使进程终止:
1.正常终止:
(a)从main返回。
(b)调用exit。
(c)调用_exit。
2.异常终止:
(a)调用abort。
(b)由一个信号终止。
(2)exit和_exit函数
exit和_exit函数用于正常终止一个程序:_exit立即进入内核,exit则先执行一些清除处理(包括调用执行各终止处理程序,关闭所有标准I/O流等),然后进入内核。exit和_exit都带一个整型参数,称之为终止状态(exit status).
#include stdlib.h void exit(int status);
#include unistd.h void _exit(int status);
三.C程序的存储空间(1)存储空间布局
*正文段。这是由CPU执行的机器指令部分。通常,正文段是可共享的,所以即使是经常执行的程序(如文本编辑程序、C编译程序、shell等)在存储器中也只需有一个副
本,另外,正文段常常是只读的,以防止程序由于意外事故而修改其自身的指令。
*初始化数据段。通常将此段称为数据段,它包含了程序中需赋初值的变量。例如,C程序中任何函数之外的说明:
int maxcount=99;
使此变量以初值存放在初始化数据段中。
*非初始化数据段。通常将此段称为bss段,这一名称来源于早期汇编程序的一个操作符,意思是block started by symbol(由符号开始的块),在程序开始执行
之前,内核将此段初始化为0。函数外的说明:
long sum[1000];
使此变量存放在非初始化数据段中。
*栈。自动变量以及每次函数调用时所需保存的信息都存放在此段中。每次函数调用时,其返回地址、以及调用者的环境信息(例如某些机器寄存器)都存放在栈中。然后,新被调用的函数在栈上为其自动和临时变量分配存储空间。通过以这种方式使用栈,C函数可以递归调用。
*堆。通常在堆中进行动态存储分配。堆位于非初始化数据段顶和栈底之间。
(2)存储器分配
ANSI C说明了三个用于存储空间动态分配的函数。
(1)malloc。分配指定字节数的存储区。此存储区中的初始值不确定。
(2)calloc。为指定长度的对象,分配能容纳其指定个数的存储空间。该空间中的每一位(bit)都初始化为0。
(3)realloc。更改以前分配区的长度(增加或减少)。当增加长度时,可能需将以前分配区的内容移到另一个足够大的区域,而新增区域内的初始值则不确定。
#include stdlib.h void*malloc(size_t size);
void*calloc(size_t obj,size_t si ze);
void*realloc(void*ptr,size_t newsi
显示全部