7 - 进程环境

Github 地址


1. main 函数

C 程序总是从 main 函数 开始执行:

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

\(argc\) 为命令行参数的数目,\(argv\) 是指向参数各个指针所构成的数组。

内核使用一个 exec 函数 执行 C 程序,在调用 main 前先调用一个特殊的启动例程。可执行程序文件将此例程指定为程序的起始地址,启动例程在调用 main 函数前从内核获取命令行参数和环境变量值。

2. 进程终止

2.1 终止类型

正常终止

  1. 从 main 返回
  2. 调用 exit
  3. 调用 _exit 和 _Exit
  4. 最后一个线程从启动例程返回
  5. 从最后一个线程调用 pthread_exit

异常终止

  1. 调用 abort
  2. 接到一个信号
  3. 最后一个线程对取消请求做出响应

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

函数 setjmplongjmp 用于在栈上跳过若干调用帧,返回到当前函数调用路径上的某一个函数中。(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 处返回的值。

函数 setjmplongjmp 用于在栈上跳过若干调用帧,返回到当前函数调用路径上的某一个函数中。(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) 笔记第七章 - 进程环境的更多相关文章

  1. (七) 一起学 Unix 环境高级编程(APUE) 之 进程关系 和 守护进程

    . . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...

  2. (十三) [终篇] 一起学 Unix 环境高级编程 (APUE) 之 网络 IPC:套接字

    . . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...

  3. Unix 环境高级编程 (APUE) 之 网络 IPC:套接字

    一起学 Unix 环境高级编程 (APUE) 之 网络 IPC:套接字 . . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级 ...

  4. (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO

    . . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...

  5. (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO

    . . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...

  6. (三) 一起学 Unix 环境高级编程 (APUE) 之 文件和目录

    . . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...

  7. (四) 一起学 Unix 环境高级编程(APUE) 之 系统数据文件和信息

    . . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...

  8. (五) 一起学 Unix 环境高级编程 (APUE) 之 进程环境

    . . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...

  9. (六) 一起学 Unix 环境高级编程 (APUE) 之 进程控制

    . . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...

随机推荐

  1. JavaSE (四)程序流程控制 -- if 、switch、for、while

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 目录 前置: * . 从键盘读取数据: 1.分支结构 1.1 if-else结构 1.2 switch- ...

  2. Java实现蓝桥杯VIP 算法训练 找公倍数

    问题描述 这里写问题描述. 打印出1-1000所有11和17的公倍数. 样例输入 一个满足题目要求的输入范例. 样例输出 与上面的样例输入对应的输出. 这道题其实没有什么可写的,但是为了让读者更方便的 ...

  3. Java实现 LeetCode 229 求众数 II(二)

    229. 求众数 II 给定一个大小为 n 的数组,找出其中所有出现超过 ⌊ n/3 ⌋ 次的元素. 说明: 要求算法的时间复杂度为 O(n),空间复杂度为 O(1). 示例 1: 输入: [3,2, ...

  4. Java实现 蓝桥杯 算法提高 成绩排序

    试题 算法提高 成绩排序 资源限制 时间限制:1.0s 内存限制:256.0MB 问题描述 给出n个学生的成绩,将这些学生按成绩排序, 排序规则,优先考虑数学成绩,高的在前:数学相同,英语高的在前:数 ...

  5. Java实现蓝桥杯正则问题

    题目描述 考虑一种简单的正则表达式: 只由 x ( ) | 组成的正则表达式. 小明想求出这个正则表达式能接受的最长字符串的长度. 例如 ((xx|xxx)x|(x|xx))xx 能接受的最长字符串是 ...

  6. Java实现无向图的欧拉回路判断问题

    1 问题描述 Problem Description 欧拉回路是指不令笔离开纸面,可画过图中每条边仅一次,且可以回到起点的一条回路.现给定一个图,问是否存在欧拉回路? Input 测试输入包含若干测试 ...

  7. Java实现 蓝桥杯 历届试题 约数倍数选卡片

    问题描述 闲暇时,福尔摩斯和华生玩一个游戏: 在N张卡片上写有N个整数.两人轮流拿走一张卡片.要求下一个人拿的数字一定是前一个人拿的数字的约数或倍数.例如,某次福尔摩斯拿走的卡片上写着数字" ...

  8. Cypress系列(14)- 环境变量详解

    如果想从头学起Cypress,可以看下面的系列文章哦 https://www.cnblogs.com/poloyy/category/1768839.html 前言 环境变量,其实就是根据环境的变化, ...

  9. 手把手教你用redis实现一个简单的mq消息队列(java)

    众所周知,消息队列是应用系统中重要的组件,主要解决应用解耦,异步消息,流量削锋等问题,实现高性能,高可用,可伸缩和最终一致性架构.目前使用较多的消息队列有 ActiveMQ,RabbitMQ,Zero ...

  10. 提高网站访问性能之Tomcat优化

    一.前言 tomcat 服务器在JavaEE项目中使用率非常高,所以在生产环境对tomcat的优化也变得非常重要了,对于tomcat的优化,主要是从2个方面入手,一是tomcat本身的配置,另一个是t ...