
APUE 第七章 进程环境
第七章 进程环境
7.2 main 函数
C程序总是从 main
函数开始执行。
1 | int main(int argc,char **argv); |
当内核执行C程序时,在调用 main
函数前先调用一个特殊的启动程序。编译器会调用连接编辑器,后者会将启动程序的地址放置在可执行文件的开始,这样启动程序就会先于 main
函数执行,并为 main
函数从内核取得命令行参数和环境变量值,为执行 main
函数做好准备。
7.3 进程终止
一共有8种方式终止进程,其中5种是正常终止
- 从
main
函数返回 - 调用
exit
函数 - 调用
_exit
或_Exit
函数 - 最后一个线程从其启动程序返回
- 最后一个线程调用
pthread_exit
异常终止有3种
- 调用
abort
- 接到一个信号
- 最后一个线程 对取消请求做出响应
退出函数
1
2
3
4
5
6
7
void exit(int status);
void _Exit(int status);
void _exit(int status);_Exit
和_exit
直接进入内核,exit
函数先执行一些清理操作后再返回内核这三个函数都有一个整型参数,称为退出状态
main
函数返回一个整型值与使用该整型值调用exit
是等价的return 0;
=exit(0);
atexit
函数进程可以登记一些函数供
exit
自动调用,这些函数被称为 终止处理程序(exit handler)。atexit
函数就是用来登记这些函数的1
2
3
4
int atexit(void (*func)(void));
//Returns: 0 if OK, nonzero on error注意,
exit
调用这些函数的顺序与它们被登记的顺序相反;如果同一个函数多次注册,那么它也会被多次调用
下图显示了一个C程序是如何启动的,以及它终止的各种方式

7.4 命令行参数
当执行一个程序时,调用 exec
的进程可将命令行参数传递给该新程序。
7.5 环境表
每个程序都能接收到一张环境表,它是一个字符指针数组,每个指针都指向一个以 null 字符结尾的C字符串(环境字符串)
环境表的地址保存在一个被称为环境指针的全局变量 environ
中
1 | extern char **environ; |
7.6 C程序的存储空间布局
C程序由下列几部分组成:
- Text segment 正文段 。包含机器指令,可共享
- Initialized data segment 初始化了的数据段 。 赋了初值的全局变量
- Uninitialized data segment 未初始化的数据段 ,也称为 bss(block started by symbol)段。没赋初值的全局变量
- Stack 栈 。 自动变量及每次函数调用需要保存的信息
- Heap 堆 。 动态内存分配

7.8 存储空间分配
ISO C 说明了3个用于存储空间动态分配的函数
- malloc 分配指定字节数的存储区。存储区中的初始值不确定
- calloc 为 指定数量指定长度的对象分配存储空间。存储区中的每一位都初始化为0
- realloc 增加或减少以前分配区的长度。
1 |
|
7.9 环境变量
环境变量以环境字符串的方式存储:
1 | name=value |
可用 getenv
函数取得环境变量的值
1 |
|
返回的指针指向 name
参数对应的 value
可用以下函数修改环境变量的值
1 |
|
这三个函数操作如下:
putenv
取形式为name=value
的字符串,将其放到环境表中,如果name
已经存在,则先删除原来的定义setenv
将name
设置为value
。如果在环境中name
已经存在,那么 1. 如果rewrite != 0
,则首先删除原来的定义; 2. 如果rewrite=0
,name
不设置为新的value
,程序也不出错unsetenv
删除name
的定义
7.10 setjmp 和 longjmp
这俩函数具有跳转功能,对于处理发生在很深层嵌套函数调用中的出错情况是非常有用的。
1 |
|
自动变量、寄存器变量和易失变量
在调用 longjmp 函数后,各种变量会恢复调用 setjmp 处的值吗?
在我的电脑上运行结果:
不进行任何编译优化的情况下,只有寄存器变量能够恢复首次调用 setjmp
时的值;
使用编译优化之后,自动变量和寄存器变量能够恢复首次调用 setjmp
时的值
7.11 getrlimit 和 setrlimit 函数
每个进程都有一组资源限制,其中一些可以用 getrlimit 和 setrlimit 函数查询和更改
1 |
|
其中 rlimit
结构体定义如下
1 | struct rlimit { |
resource
可选下列值
