《UNIX环境高级编程》(APUE) 笔记第七章 - 进程环境
7 - 进程环境
1. main 函数
C 程序总是从 main 函数 开始执行:
int main(int argc, char *argv[]);
\(argc\) 为命令行参数的数目,\(argv\) 是指向参数各个指针所构成的数组。
内核使用一个 exec 函数 执行 C 程序,在调用 main 前先调用一个特殊的启动例程。可执行程序文件将此例程指定为程序的起始地址,启动例程在调用 main 函数前从内核获取命令行参数和环境变量值。
2. 进程终止
2.1 终止类型
正常终止:
- 从 main 返回
- 调用 exit
- 调用 _exit 和 _Exit
- 最后一个线程从启动例程返回
- 从最后一个线程调用 pthread_exit
异常终止:
- 调用 abort
- 接到一个信号
- 最后一个线程对取消请求做出响应
2.2 退出函数
三个函数用于正常终止一个程序:
#include <stdlib.h>
void exit(int status);
void _Exit(int status);
#include <unistd.h>
void _exit(int status);
exit 函数总是执行一个标准 I/O 库的清理关闭操作:对于所有打开流调用 fclose 函数,这造成输出缓冲中的所有数据都被冲洗(写到文件上)。
_exit 和 _Exit 立即进入内核。
2.3 atexit
由 exit 函数自动调用的函数是 终止处理程序 (exit handler) ,调用 atexit 函数来登记这些函数:
#include <stdlib.h>
int atexit(void (*func)(void));
返回值:若成功,返回 \(0\) ;若出错,返回 \(非0\) 。
atexit 的参数是一个函数地址。exit 函数调用这些函数的顺序与它们登记时候的顺序相反。同一函数如若登记多次,也会被调用多次。( exit 首先调用各终止处理程序,然后关闭 (fclose) 所有打开流 )

3. 环境表
每个程序都接收到一张 环境表 ,它是一个字符指针数组,各指针指向的字符串称为 环境字符串 。全局变量 environ 为 环境指针 ,包含了该指针数组的地址。
extern char **environ;

4. C 程序的存储空间布局
C 程序存储空间包括:
- 正文段:这是由CPU执行的机器指令部分。通常,正文段可共享,且是只读的,以防止程序由于以外而修改其指令。
- 初始化数据段:称为 数据段 ,包含了程序中需要明确赋初值的变量。
- 未初始化数据段:称为 bss 段 ,在程序开始执行前,内核将此段中的数据初始化为 \(0\) 或空指针。
- 栈:保存自动变量(局部作用域变量)以及每次函数调用时所需保存的信息(其返回地址以及调用者的环境信息)。最近被调用的函数在栈上为其自动和临时变量分配存储空间,通过这种方式使用栈,C递归函数可以工作。
- 堆:在堆中进行动态存储分配。
需要存储在磁盘程序文件中的段只有正文段和初始化数据段。

5. 共享库
- 共享库 使得可执行文件中不再需要包含公用的库函数,而只需在所有进程都可引用的存储区中保存这种库例程的一个副本。
- 程序第一次执行或调用某个库函数时,用 动态链接 的方法将程序与共享库函数相链接。
- 这减少了执行文件长度,但增加了一些运行时间开销。这种开销发生在该程序第一次被执行时,或者每个共享库函数第一次被调用时。
6. 存储空间分配
三个用于 存储空间动态分配 的函数:
- malloc:分配指定字节数的存储区。此存储区中的初始值不确定。
- calloc:为指定数量指定长度的对象分配存储空间。该存储空间中的每一位 (bit) 都初始化为 \(0\) 。
- realloc:增加或减少以前分配区的长度。当增加长度时,可能需要将以前分配区的内容移到另一个足够大的区域,以便在尾端提供增加的存储区,而新增区域内的初始值不确定。\(newsize\) 是存储区的长度。
free 函数用于释放 \(ptr\) 指向的存储空间,被释放的空间通常被送入可用存储区池。若一个进程调用 malloc 函数,但却忘记了调用 free 函数,那么该进程占用的存储空间就会连续增加,这被称为 泄露 (leakage) 。
#include <stdlib.h>
void *malloc(size_t size);
void *calloc(size_t nobj, size_t size);
void *realloc(void *ptr, size_t newsize);
//三个函数返回值:若成功,返回非空指针;若出错,返回 NULL
void free(void *ptr);
7. 函数 setjmp 和 longjmp
函数 setjmp 和 longjmp 用于在栈上跳过若干调用帧,返回到当前函数调用路径上的某一个函数中。(C语言 goto 语句在一个函数内实施跳转,两者不同)
#include <setjmp.h>
int setjmp(jmp_buf env); //返回值:若直接调用,返回 0,从longjmp返回,则为非 0
void longjmp(jmp_buf env, int val);
在希望返回到的位置调用 setjmp 。\(env\) 参数的类型是一个特殊类型 jmp_buf ,它是某种形式的数组,其中存放调用 longjmp 时能用来恢复栈状态的所有信息。通常将 \(env\) 变量定义成全局变量。\(val\) 为从 setjmp 处返回的值。
函数 setjmp 和 longjmp 用于在栈上跳过若干调用帧,返回到当前函数调用路径上的某一个函数中。(C语言 goto 语句在一个函数内实施跳转,两者不同)
#include <setjmp.h>
int setjmp(jmp_buf env); //返回值:若直接调用,返回 0,从longjmp返回,则为非 0
void longjmp(jmp_buf env, int val);
在希望返回到的位置调用 setjmp 。\(env\) 参数的类型是一个特殊类型 jmp_buf ,它是某种形式的数组,其中存放调用 longjmp 时能用来恢复栈状态的所有信息。通常将 \(env\) 变量定义成全局变量。\(val\) 为从 setjmp 处返回的值。
《UNIX环境高级编程》(APUE) 笔记第七章 - 进程环境的更多相关文章
- (七) 一起学 Unix 环境高级编程(APUE) 之 进程关系 和 守护进程
. . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...
- (十三) [终篇] 一起学 Unix 环境高级编程 (APUE) 之 网络 IPC:套接字
. . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...
- Unix 环境高级编程 (APUE) 之 网络 IPC:套接字
一起学 Unix 环境高级编程 (APUE) 之 网络 IPC:套接字 . . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级 ...
- (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO
. . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...
- (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO
. . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...
- (三) 一起学 Unix 环境高级编程 (APUE) 之 文件和目录
. . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...
- (四) 一起学 Unix 环境高级编程(APUE) 之 系统数据文件和信息
. . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...
- (五) 一起学 Unix 环境高级编程 (APUE) 之 进程环境
. . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...
- (六) 一起学 Unix 环境高级编程 (APUE) 之 进程控制
. . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...
随机推荐
- SpringMVC(一)概述、解析器与注解
个人博客网:https://wushaopei.github.io/ (你想要这里多有) 一.SpringMVC的概述 1.概述 Spring MVC框架是一个开源的Java平台,为开发强大的基 ...
- Spring ( 四 )Spring的AOP动态代理、切面编程
个人博客网:https://wushaopei.github.io/ (你想要这里多有) 一.AOP切面编程 1.什么是AOP AOP是面向切面编程.全称:Aspect Oriented Pro ...
- QTI EAS学习之find_energy_efficient_cpu
Energy Awareness Scheduler是由ARM和Linaro开发的新的linux kernel调度器. 原先CFS调度器是基于policy进行调度,并有不同的吞吐量.例如,有一个新的t ...
- Java实现 蓝桥杯VIP 算法训练 s01串
题目描述 s01串初始为" 0" 按以下方式变换 0变1,1变01 数据规模和约定 0~19 输入 1个整数(0~19) 输出 n次变换后s01串 样例输入 3 样例输出 101 ...
- Java实现 LeetCode 216. 组合总和 III(三)
216. 组合总和 III 找出所有相加之和为 n 的 k 个数的组合.组合中只允许含有 1 - 9 的正整数,并且每种组合中不存在重复的数字. 说明: 所有数字都是正整数. 解集不能包含重复的组合. ...
- java实现第七届蓝桥杯阶乘位数
阶乘位数 阶乘位数 9的阶乘等于:362880 它的二进制表示为:1011000100110000000 这个数字共有19位. 请你计算,9999 的阶乘的二进制表示一共有多少位? 注意:需要提交的是 ...
- Java实现第八届蓝桥杯承压计算
承压计算 题目描述 X星球的高科技实验室中整齐地堆放着某批珍贵金属原料. 每块金属原料的外形.尺寸完全一致,但重量不同. 金属材料被严格地堆放成金字塔形. 7 5 8 7 8 8 9 2 7 2 8 ...
- java实现第六届蓝桥杯九数组分数
九数组分数 九数组分数 1,2,3...9 这九个数字组成一个分数,其值恰好为1/3,如何组法? 下面的程序实现了该功能,请填写划线部分缺失的代码. public class A { public s ...
- Linux 文件特殊权限-SetGID
SUID只针对二进制可执行文件,而SGID可以针对二进制文件,这时它和SUID非常类似,命令执行在执行程序的时候,组身份变换为该文件的属组,最常见的locate命令,普通用户也可以搜索文件目录,它也可 ...
- 原声js数组去重方法
数组去重方法 方法一 ---- 利用数组filter + indexOf方法去重 方法二 ---- 利用数组forEach + indexOf方法去重 方法三 ---- 利用数组from方法 + Se ...