【Linux从0到1】第六篇:进程概念(下)

发布时间:2024-05-25 08:01

文章目录

  • 一、环境变量
    • 1.1 基本概念
    • 1.2 常见环境变量
    • 1.3 查看环境变量方法
    • 1.4 测试PATH
    • 1.5 和环境变量相关的命令
    • 1.6 环境变量的组织方式
  • 二、程序地址空间
    • 2.1 程序地址空间
    • 2.2 Linux2.2 内核进程调度队列-选学
    • 2.3 优先级
    • 2.4 活动队列 & 过期队列
    • 2.5 active指针和expired指针


一、环境变量

1.1 基本概念

  • 环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数
  • 如:我们在编写C/C++代码的时候,在链接的时候,从来不知道我们的所链接的动态静态库在哪里,但是照样可以链接成功,生成可执行程序,原因就是有相关环境变量帮助编译器进行查找。
  • 环境变量通常具有某些特殊用途,还有在系统当中通常具有全局特性。
    \"【Linux从0到1】第六篇:进程概念(下)_第1张图片\"

1.2 常见环境变量

  • PATH : 指定命令的搜索路径
  • HOME : 指定用户的主工作目录(即用户登陆到Linux系统中时,默认的目录)
  • SHELL : 当前Shell,它的值通常是/bin/bash。

1.3 查看环境变量方法

echo $NAME //NAME:你的环境变量名称

\"在这里插入图片描述\"
\"在这里插入图片描述\"
\"在这里插入图片描述\"

1.4 测试PATH

1.创建myproc.c
\"【Linux从0到1】第六篇:进程概念(下)_第2张图片\"

2.对比./myproc执行和之间myproc执行
3. 为什么有些指令可以直接执行,不需要带路径,而我们的二进制程序需要带路径才能执行?
4. 将我们的程序所在路径加入环境变量PATH当中, export PATH=$PATH:myproc程序所在路径
\"【Linux从0到1】第六篇:进程概念(下)_第3张图片\"
\"【Linux从0到1】第六篇:进程概念(下)_第4张图片\"

  1. 对比测试
  2. 还有什么方法可以不用带路径,直接就可以运行呢?

1.5 和环境变量相关的命令

\"【Linux从0到1】第六篇:进程概念(下)_第5张图片\"

  1. echo: 显示某个环境变量值

  2. export: 设置一个新的环境变量

  3. env: 显示所有环境变量
    \"【Linux从0到1】第六篇:进程概念(下)_第6张图片\"

  4. set: 显示本地定义的shell变量和环境变量
    \"【Linux从0到1】第六篇:进程概念(下)_第7张图片\"

  5. unset: 清除环境变量

1.6 环境变量的组织方式

\"【Linux从0到1】第六篇:进程概念(下)_第8张图片\"
每个程序都会收到一张环境表,环境表是一个字符指针数组,每个指针指向一个以’\\0’结尾的环境字符串.
通过代码如何获取环境变量

  • 命令行第三个参数(了解)
    \"【Linux从0到1】第六篇:进程概念(下)_第9张图片\"
    \"【Linux从0到1】第六篇:进程概念(下)_第10张图片\"

\"【Linux从0到1】第六篇:进程概念(下)_第11张图片\"
\"【Linux从0到1】第六篇:进程概念(下)_第12张图片\"
\"【Linux从0到1】第六篇:进程概念(下)_第13张图片\"

  • 通过第三方变量environ获取(了解)
    \"【Linux从0到1】第六篇:进程概念(下)_第14张图片\"
    \"【Linux从0到1】第六篇:进程概念(下)_第15张图片\"
    \"【Linux从0到1】第六篇:进程概念(下)_第16张图片\"
    libc中定义的全局变量environ指向环境变量表,environ没有包含在任何头文件中,所以在使用时 要用extern声明。

  • 通过系统调用获取或设置环境变量(重点掌握)
    getenv , 本次讲解
    setenv , 后面讲解
    \"【Linux从0到1】第六篇:进程概念(下)_第17张图片\"
    \"【Linux从0到1】第六篇:进程概念(下)_第18张图片\"
    \"【Linux从0到1】第六篇:进程概念(下)_第19张图片\"
    常用getenv和setenv函数来访问特定的环境变量。

环境变量通常是具有全局属性的
\"【Linux从0到1】第六篇:进程概念(下)_第20张图片\"
\"【Linux从0到1】第六篇:进程概念(下)_第21张图片\"
\"【Linux从0到1】第六篇:进程概念(下)_第22张图片\"
\"【Linux从0到1】第六篇:进程概念(下)_第23张图片\"
\"【Linux从0到1】第六篇:进程概念(下)_第24张图片\"
\"【Linux从0到1】第六篇:进程概念(下)_第25张图片\"

二、程序地址空间

2.1 程序地址空间

\"【Linux从0到1】第六篇:进程概念(下)_第26张图片\"
验证一下:
\"【Linux从0到1】第六篇:进程概念(下)_第27张图片\"
\"【Linux从0到1】第六篇:进程概念(下)_第28张图片\"
注意:上面这个不是真的内存!!那么它是什么呢?它是进程虚拟地址空间
下面验证一下:
\"【Linux从0到1】第六篇:进程概念(下)_第29张图片\"
\"【Linux从0到1】第六篇:进程概念(下)_第30张图片\"
我们发现,输出出来的变量值和地址是一模一样的,很好理解呀,因为子进程按照父进程为模版,父子并没有对变量进行进行任何修改。可是将代码稍加改动:
\"【Linux从0到1】第六篇:进程概念(下)_第31张图片\"
\"【Linux从0到1】第六篇:进程概念(下)_第32张图片\"
我们发现,父子进程,输出地址是一致的,但是变量内容不一样!能得出如下结论:

  • 变量内容不一样,所以父子进程输出的变量绝对不是同一个变量
  • 但地址值是一样的,说明,该地址绝对不是物理地址!
  • 在Linux地址下,这种地址叫做 虚拟地址
  • 我们在用C/C++语言所看到的地址,全部都是虚拟地址!物理地址,用户一概看不到,由OS统一管理

OS必须负责将 虚拟地址 转化成 物理地址 。
进程地址空间
所以之前说‘程序的地址空间’是不准确的,准确的应该说成 进程地址空间 ,那该如何理解呢?
\"【Linux从0到1】第六篇:进程概念(下)_第33张图片\"
\"【Linux从0到1】第六篇:进程概念(下)_第34张图片\"

上面的图就足矣说名问题,同一个变量,地址相同,其实是虚拟地址相同,内容不同其实是被映射到了不同的物理地址。
为什么要有地址空间:
1.通过添加一层软件层,完成有效的对进程操作内存进行风险管理(权限管理), 本质的目的是为了保护物理内存已经各个进程的数据安全。
\"【Linux从0到1】第六篇:进程概念(下)_第35张图片\"
2.将内存申请和内存使用的概念在时间上划分清楚,通过虚拟地址空间,来屏蔽底层申请内存的过程,达到进读写内存和OS进行内存管理操作,进行软件上面的分离。
\"【Linux从0到1】第六篇:进程概念(下)_第36张图片\"
3.站在CPU和应用层的角度,进程可以统一看做统一使用4GB的空间,而且每个空间区域的相对位置,是比较确定的!
\"【Linux从0到1】第六篇:进程概念(下)_第37张图片\"
补充:
\"【Linux从0到1】第六篇:进程概念(下)_第38张图片\"
这内核空间存的是什么呢?
\"【Linux从0到1】第六篇:进程概念(下)_第39张图片\"
\"【Linux从0到1】第六篇:进程概念(下)_第40张图片\"

2.2 Linux2.2 内核进程调度队列-选学

\"【Linux从0到1】第六篇:进程概念(下)_第41张图片\"
上图是Linux2.6内核中进程队列的数据结构,之间关系也已经给大家画出来,方便大家理解

2.3 优先级

普通优先级: 100~ 139(我们都是普通的优先级,想想nice值的取值范围,可与之对应!)
实时优先级: 0~ 99(不关心)

2.4 活动队列 & 过期队列

活动队列:

  • 时间片还没有结束的所有进程都按照优先级放在该队列
  • nr_active: 总共有多少个运行状态的进程
  • queue[140]: 一个元素就是一个进程队列,相同优先级的进程按照FIFO规则进行排队调度,所以,数组下标就是优先级!
  • 从该结构中,选择一个最合适的进程,过程是怎么的呢?
  1. 从0下表开始遍历queue[140]
  2. 找到第一个非空队列,该队列必定为优先级最高的队列
  3. 拿到选中队列的第一个进程,开始运行,调度完成!
  4. 遍历queue[140]时间复杂度是常数!但还是太低效了!
    bitmap[5]:一共140个优先级,一共140个进程队列,为了提高查找非空队列的效率,就可以用5*32个
    比特位表示队列是否为空,这样,便可以大大提高查找效率!

过期队列

  • 过期队列和活动队列结构一模一样
  • 过期队列上放置的进程,都是时间片耗尽的进程
  • 当活动队列上的进程都被处理完毕之后,对过期队列的进程进行时间片重新计算

2.5 active指针和expired指针

  • active指针永远指向活动队列
  • expired指针永远指向过期队列
  • 可是活动队列上的进程会越来越少,过期队列上的进程会越来越多,因为进程时间片到期时一直都存在的。
  • 没关系,在合适的时候,只要能够交换active指针和expired指针的内容,就相当于有具有了一批新的活动进程!

ItVuer - 免责声明 - 关于我们 - 联系我们

本网站信息来源于互联网,如有侵权请联系:561261067@qq.com

桂ICP备16001015号