石碣镇做网站,帮别人做网站开价,网站开发所以浏览器兼容模式,网站 关键词【README】
1.本文内容总结自 B站 《操作系统-哈工大李治军老师》#xff0c;内容非常棒#xff0c;墙裂推荐#xff1b;
2.为什么要讲线程呢。实际要讲进程的切换#xff1b;进程的切换包括切换指令#xff0c;切换资源#xff1b;切换指令就是切换线程#xff08;简…【README】
1.本文内容总结自 B站 《操作系统-哈工大李治军老师》内容非常棒墙裂推荐
2.为什么要讲线程呢。实际要讲进程的切换进程的切换包括切换指令切换资源切换指令就是切换线程简单讲线程就是程序指令线程的切换就是程序指令的切换
进程必须在内核中切换进程实际上是切换内核级线程而不是用户级线程但切换用户级线程是切换内核级线程的一部分
2为什么没有用户级进程
因为进程要分配资源如访问内存所以必须进入内核态才能访问这些资源【1】开始核心级线程 1 多核多个物理cpu但共用同一个缓存同一个MMU内存映射单元 2多处理器多个物理cpu每个cpu有自己的缓存自己的MMU内存映射单元
【补充1】内存映射单元
内存逻辑地址 与 内存物理地址 映射表
【补充2】并发与并行区别
并发交替执行单核运行多个线程相互有影响并行同时执行多个线程在多个物理核上运行可以理解一个核运行一个线程相互独立不干扰
3用户级线程与内核级线程
用户级线程缺点操作系统看不到操作系统无法分配硬件没有发挥出多核价值多进程也无法发挥多核价值因为只有一套MMU无法做到多个进程同时执行内核级线程优点 操作系统可以看到为每个线程分配一个cpu发挥出多核价值多个内核线程可以同时执行并行执行【1.1】内核级线程原理 1要有核心级线程需要既在用户态用户栈运行也在内核态内核栈运行 所以 每个内核级线程需要一套栈包括用户栈内核栈而不一个栈 即 内核线程切换需要TCB切换一套栈切换用户栈和内核栈 【1.2】用户栈与内核栈
1用户栈与内核栈组成同一个线程的一套栈 2INT 0x80 中断指令使得 进程线程从用户态切换到内核态 3进入内核态前把线程的用户栈信息元数据压入到内核栈即把同一个线程的用户栈与内核栈关联起来如下表所示 内核栈栈元素 含义对应用户栈的寄存器值 源SS 用户态的ss寄存器值 ss 指的是堆栈段寄存器存放栈的段基址内存是分段使用的 源SP 用户态的栈指针寄存器值 sp指的是堆栈指针寄存器存放栈的偏移地址 说的直白点 栈基址栈起始内存地址段基址左移n位 加上偏移地址如n取4 EFLAGS 用户态的标志寄存器值 源PC 用户态的pc寄存器值 pc程序计数器寄存器 源CS 用户态的cs寄存器值cs代码段寄存器
4用户栈与内核栈的关联 5 IRET 从内核态切换到用户态
出栈把内存中内核栈的5个寄存器值弹出到cpu的寄存器中回到用户态
6用户态切换到内核态的步骤 6.1) sys_read() 启动磁盘读把自己变成阻塞状态等待磁盘控制器响应时当前线程阻塞cpu需要切换运行其他线程 6.2switch_to(cur, next) 切换到下一个内核线程 cur表示当前线程tcbnext表示下一个线程tcb具体过程
通过线程tcb找到内核栈指针通过ret切换到某个内核程序用cs:pc 切换到用户程序上图中 线程S调用函数A 线程T调用函数C
PC?? 表示 线程T的用户态代码CS?? 表示 线程T的用户态代码???? 表示 iret指令从中断返回
6.3内核线程切换 switch_to 实际上是对两套栈的切换每套栈包含用户栈和内核栈 【2】内核线程切换switch_to 五段论*非常重要 1五段论步骤 步骤 描述 1 用户态1切换到内核态1 把用户态1的物理寄存器的值保存到内核栈1完成用户栈切换到内核栈 2 执行读磁盘等中断操作触发中断 3 因为中断调用 switch_to 切换到其他内核线程如线程2 4 Switch_to函数找到内核线程2的tcb通过tcb找到内核线程2的内核栈2 切换到内核栈2完成内核栈间的切换 5 通过 iret 把内核栈2中保存的用户态2的寄存器值弹出到物理寄存器 即 ss:sp, cs:ip 通过内核栈2的用户态寄存器值赋值从而完成从内核态2切换到用户态2完成内核栈切换到用户栈 用户线程与内核线程用户线程与内核线程实际上同一个线程
当操作的内存空间在用户态则是用户线程当操作的内存空间在内核态则是内核线程
2附加段进程切换S,T
进程切换还需要切换映射表
3创建线程代码细节 tcb 是对线程的结构体抽象 void threadCreate() { TCB tcb get_free_page(); // 申请一段内存作为tcb *krlstatck …; // 申请一段内存作为内核栈 *userstack 传入 // 用户栈 填写两个stack // 内核栈与用户栈初始化 tcb.esp krlstack; // tcb 关联内核栈 tcb.状态就绪// 状态为就绪 tcb入队 } 4用户级线程与核心级线程对比 用户灵活性 用户线程大于核心线程 原因
用户线程的调度开发人员可以自己编写调度策略进行控制如调用 yield让出cpu而内核级线程无法修改调度即内核线程调度策略是操作系统写死的无法修改