当前课程知识点:Linux 内核分析与应用 > 第3章 进程管理 > 3.1 进程概述 > Video
大家好 这一讲我们对于Linux内核中的进程呢
进行一个初步的概述
从这个图里面我们看到呢
一个程序通过编译器将其编译成汇编程序
经过汇编器将其会汇编成目标代码
通过链接器形成可执行文件a.out或者elf格式
最后交给操作系统来执行 那么问题来了
操作系统如何应对千变万化的程序
通过这张图我们看到呢
当一个程序一旦执行 程序也摇身一变为进程
在OS看来 每个进程是没有多大差异性的
都被封装在这样的可执行文件格式中
在内存管理一章 我们将继续详细介绍进程的执行和加载
那么在用户态下呢
我们可以通过top命令感知系统中
各个进程以及动态变化 如图
下面我们来介绍一下进程的家族关系
进程是一个动态的实体
它具有生命周期的
系统中进程的生生死死随时发生
因此呢操作系统对进程的描述模仿人类的活动
一个进程不会平白无故的诞生
它总会有自己的父母
在Linux中呢
通过调用fork系统调用来创建一个新的进程
新创建的进程同样也能执行fork
所以呢可以形成一颗完整的进程树
如图呢是Linux系统启动以后形成的一棵树
可以通过ps命令查看自己机子上的进程树
那么我们如何描述进程的属性
Linux内核中把对进程的描述结构叫做task_struct结构
那么传统的教科书中 这样的数据结构被叫做进程控制块(PCB)
在内核源代码中具体定义在sched.h文件中
我们在这里列出进程控制块的各种信息的分类
因为进程控制块中的信息非常多
多达几百个字段 为了有助于大家对它认识呢 这里对它进行了分类
包括进程的状态信息
链接信息 各种标识符
调度信息 进程间的通信信息
虚拟内存的信息 文件系统的信息
处理器环境的信息等等
涉及到进程方方面面
具体可以通过查看源代码对它们逐渐的认识
那么首先呢我们来介绍进程的状态以及转换
我们说状态呢是用来描述进程的动态变化的
那么状态最基本的呢有三种
分别为就绪态 睡眠态和运行态
在具体的操作系统中 可能实例化出多个状态
如图给出Linux中进程5种状态
那么我们把就绪态和运行态呢
合并为一个状态叫就绪态
调度程序从就绪队列中选择一个进程投入运行
睡眠态呢又分为两种
浅度睡眠(很容易被唤醒)和深度睡眠
除此之外呢还有暂停状态
和僵死状态 也就是进程死亡但没有释放其PCB
这里我们给出Linux源代码中对于状态的定义
请大家观察一下呢这样的定义有什么特点呢
为什么每个状态的值定义为2的n次方
这里我们给出的呢是在
在源代码中 状态的真正的表示形式
大家可以查看相关的源代码
那么上面一张图给出了进程之间的亲属关系
我们说系统在创建的进程时候呢
具有父/子关系
因为一个进程能创建几个子进程
而子进程之间呢有兄弟关系
在PCB中引入几个域来表示这些关系如前所述
进程1(init)是所有进程的祖先
系统中的进程形成一颗进程树
为了描述进程之间的父/子及兄弟关系呢
在进程的PCB中就要引入几个域
假设P呢表示一个进程
首先有一个域描述它的父亲(parent)
其次呢有一个域描述P的子进程
因为子进程不止一个 因此让这些域指向年龄最小的子进程(child)
最后呢P可能有兄弟
于是呢用一个域描述P的长兄进程(old sibling)
那么一个域描述P的弟进程(younger sibling)
从这些关系看到呢
进程完全模拟人类的生存状态
你自己可以试图扮演进程的角色
那么上面通过对进程状态
标识符及亲属关系的描述呢
我们可以把这些域描述如下
其中呢有进程的状态标识符
进程之间的亲属关系
同样呢我们要
进入源码进行查看 才能有身临其境的感觉
task_struct结构位于sched.h中呢
这里列出的是部分代码的片段
那么 进程控制块存放在内存的什么地方呢
实际上Linux内核为了节省空间
把内核栈和一个紧挨着的PCB的小数据结构
thread_info放在一起呢
占用8KB的内存区 如下图所示
在内核代码中如何体现呢
实际上 它是这样一个混合结构
在这个结构中 我们可以看到呢
一个大小为8KB的栈
在x86上呢thread_info的定义呢如下
在这个结构里我们看到thread_info表示呢
硬件关系更密切的数据
第一个字段就是task_sturct结构
随着Linux版本的变化呢 进程控制块的内容越来越多
所需的空间也越来越大
这样就使得留给内核的堆栈空间变小了
因此呢把部分进程控制块的内容移出这个空间
只保留访问频繁的thread_info
那么把PCB与内核栈放在一起有什么好处呢
有两方面的好处
第一呢内核可以方便而快速地找到PCB
只要知道栈指针呢就可以找到PCB的起始地址
用伪代码描述如下
第二呢可以避免在创建进程时动态分配额外的内存
另外在Linux中呢为了表示当前正在运行的进程
定义了一个current宏可以用它呢
作全局变量来使用
例如current->pid返回正在执行的进程的标识符
那么内核中如何对进程进行组织
它有各种各样的组织方式
这里我们给出进程的链表组织方式
那么我们看到链表的头和尾都为init_task
这是0号进程的PCB
我们可以进入源代码查看其具体各个字段的值
0号这个进程永远不会被撤消
它的PCB被静态地分配在
内核的数据段中
也就是说init_task的PCB呢
是预先由编译器分配的
在运行的过程中保持不变
而其它PCB是在进程运行的过程中
由系统根据当前的内存状况
随机分配的 撤消时再归还给系统
下面呢我们自己编写一个内核模块
打印系统中所有进程的PID和进程名
模块中的代码如下
在这个例子中 我们仅仅打印出PCB中的2个字段
其实呢你可以举一反三
打印出更多字段来观察进程执行过程中
各个具体字段的具体值
容器作为目前云技术的核心技术
与进程到底有多大关系呢
对进程来说 它的静态表现就是程序
平时呢都安安静静地待在磁盘上
而一旦运行起来呢它就变成了计算机里的数据
和状态的总和这就是它的动态表现
而容器技术的核心功能呢
就是通过约束和修改进程的动态表现
从而为其创建一个“边界”
对于Docker等大多数Linux容器来说呢
Cgroups技术是用来
制造约束的主要手段
而Namespace技术则是用来修改进程视图的主要方法
在此我们抛砖引玉
感兴趣的同学可以进一步探讨下去
那么参考资料呢介绍大家
阅读深入理解Linux内核第三版第三章
Linux内核设计与实现第三版第三章
好 谢谢大家
-1.1 Linux操作系统概述
-1.2 Linux内核结构以及内核模块编程
--Video
-1.3 Linux内核源码中的双链表结构
--Video
-1.4 源码分析-内核中的哈希表
--Video
-1.5 动手实践-Linux内核模块的插入和删除
--Video
-第1章 概述--章节测验
-2.1 内存管理之内存寻址
--Video
-2.2 段机制
--Video
-2.3分页机制
--Video
-2.4 动手实践-把虚拟地址转换成物理地址
--Video
-第2章 内存寻址--章节测验
-3.1 进程概述
--Video
-3.2 Linux进程创建
--Video
-3.3 Linux进程调度
--Video
-3.4 动手实践-打印进程描述符task_struct中的字段
--Video
-3.5工程实践-基于内核模块的负载监控
--Video
-第3章 进程管理--章节测验
-4.1 Linux内存管理机制
--Video
-4.2 进程用户空间管理机制
--Video
-4.3 物理内存分配与回收机制(上)
--Video
-4.4 物理内存分配与回收机制(下)
--Video
-4.5 动手实践-Linux内存映射基础(上)
--Video
-4.6 动手实践-Linux内存映射实现(中)
--Video
-4.7 动手实践-Linux内存映射测试(下)
--Video
-4.8 初学者对内存管理的常见疑惑
-第4章 内存管理--章节测验
-5.1 中断机制概述
--Video
-5.2 中断处理机制
--Video
-5.3 中断下半部处理机制
--Video
-5.4 时钟中断机制
--Video
-5.5 动手实践-中断上半部的代码分析及应用
--Video
-5.6 动手实践-中断下半部的代码分析及应用
--Video
-第5章 中断--章节测验
-6.1 Linux中的各种API
--Video
-6.2 系统调用机制
--Video
-6.3 动手实践-添加系统调用(系统调用日志收集系统)
--Video
-第6章 系统调用--章节测验
-7.1 内核同步概述
--Video
-7.2 内核同步机制
--Video
-7.3 动手实践-内核多任务并发实例(上)
--Video
-7.4 动手实践-内核多任务并发实例(下)
--Video
-第7章 内核同步--章节测验
-8.1 虚拟文件系统的引入
--Video
-8.2 虚拟文件系统的主要数据结构
--Video
-8.3 文件系统中的各种缓存
--Video
-8.4 页高速缓存机制以及读写
--Video
-8.5 动手实践-编写一个文件系统(上)
--Video
-8.6 动手实践-编写一个文件系统(中)
--Video
-8.7 动手实践-编写一个文件系统(下)
--Video
-第8章 文件系统--章节测验
-9.1 设备驱动概述
--Video
-9.2 I/O空间管理
--Video
-9.3 设备驱动模型
--Video
-9.4 字符设备驱动程序简介
--Video
-9.5 块设备驱动程序简介
--Video
-9.6 动手实践-编写字符设备驱动程序
--Video
-9.7工程实践-编写块设备驱动的基础(上)
--Video
-9.8 工程实践-块设备驱动程序分析(中)
--Video
-9.9 工程实践-块设备驱动程序实现(下)
--Video
-第9章 设备驱动--章节测验
-致谢与说明
--Video