《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 环境高级编 ...
随机推荐
- Java实现 LeetCode 669 修剪二叉搜索树(遍历树)
669. 修剪二叉搜索树 给定一个二叉搜索树,同时给定最小边界L 和最大边界 R.通过修剪二叉搜索树,使得所有节点的值在[L, R]中 (R>=L) .你可能需要改变树的根节点,所以结果应当返回 ...
- Java实现 LeetCode 496 下一个更大元素 I
496. 下一个更大元素 I 给定两个没有重复元素的数组 nums1 和 nums2 ,其中nums1 是 nums2 的子集.找到 nums1 中每个元素在 nums2 中的下一个比其大的值. nu ...
- Java实现 蓝桥杯VIP 基础练习 2n皇后问题
基础练习 2n皇后问题 时间限制:1.0s 内存限制:512.0MB 问题描述 给定一个n*n的棋盘,棋盘中有一些位置不能放皇后.现在要向棋盘中放入n个黑皇后和n个白皇后,使任意的两个黑皇后都不在同一 ...
- 第四届蓝桥杯JavaC组省赛真题
解题代码部分来自网友,如果有不对的地方,欢迎各位大佬评论 题目1.猜年龄 题目描述 美国数学家维纳(N.Wiener)智力早熟,11岁就上了大学.他曾在1935~1936年应邀来中国清华大学讲学. 一 ...
- Java实现 蓝桥杯 算法提高最小方差生成树
1 问题描述 给定带权无向图,求出一颗方差最小的生成树. 输入格式 输入多组测试数据.第一行为N,M,依次是点数和边数.接下来M行,每行三个整数U,V,W,代表连接U,V的边,和权值W.保证图连通.n ...
- java实现第六届蓝桥杯密文搜索
密文搜索 福尔摩斯从X星收到一份资料,全部是小写字母组成. 他的助手提供了另一份资料:许多长度为8的密码列表. 福尔摩斯发现,这些密码是被打乱后隐藏在先前那份资料中的. 请你编写一个程序,从第一份资料 ...
- java实现第七届蓝桥杯路径之谜
路径之谜 题目描述 小明冒充X星球的骑士,进入了一个奇怪的城堡. 城堡里边什么都没有,只有方形石头铺成的地面. 假设城堡地面是 n x n 个方格.[如图1.png]所示. 按习俗,骑士要从西北角走到 ...
- UVIYN的基本设置
- javaScript的执行机制-同步任务-异步任务-微任务-宏任务
一.概念理解 1.关于javascript javascript是一门单线程语言,在最新的HTML5中提出了Web-Worker,但javascript是单线程这一核心仍未改变.所以一切javascr ...
- Spring Cloud 系列之 Alibaba Nacos 注册中心(一)
前言 从本章节开始,我们学习 Spring Cloud Alibaba 相关微服务组件. Spring Cloud Alibaba 介绍 Spring Cloud Alibaba 致力于提供微服务开发 ...