【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)用户栈与内核栈组成同一个线程的一套栈;
2)INT 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.2)switch_to(cur, next)
切换到下一个内核线程; cur表示当前线程tcb,next表示下一个线程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;
  • 而内核级线程无法修改调度,即内核线程调度策略是操作系统写死的,无法修改;

8.内核级线程(核心级线程)相关推荐

  1. 操作系统--用户级线程与内核级线程

    一.多进程是操作系统基本图像 进程都是在内核进行 二.用户级线程 2.1线程引入 可以切指令不切表,也就是资源不动,指令执行分开,更加轻量化,从而提高效率,保留并发优点,避免进程切换代价,也就引入了线 ...

  2. 操作系统(李治军) L12内核级线程的实现

    只有支持了进程才可以管理CPU 图:五段论 整个过程:从用户栈->内核栈->TCB->TCB完成切换(TCB用switch_to完成TCB的切换完成内核栈的切换)->内核栈切换 ...

  3. 操作系统(李治军) L11内核级线程

    **用户级和核心级的区别:根据TCB切换一个栈还是一套栈** 进入内核要用中断 INT和IRET压栈来使寄存器的状态指令从用户栈和内核栈来回切换 ESP:系统分区 cur,next当前和下一个线程的T ...

  4. 哈工大操作系统学习笔记五——内核级线程实现

    哈工大os学习笔记五(内核级线程实现) 文章目录 哈工大os学习笔记五(内核级线程实现) 一. 中断入口.中断出口(前后两段) 1. 从int中断进入内核(中断入口第一段) 2.中断出口(最后一段) ...

  5. 应用退出前不让线程切换_用户级线程和内核级线程,你分清楚了吗?

    前天晚上有个伙伴私信我说在学进程和线程,问我有没有好的方法和学习教程,刚好我最近也在备相关的课. 班上不少学生学的还是很不错的.拿班上小白和小明的例子吧(艺名哈).小明接受能力很强,小白则稍差些. 关 ...

  6. OS / 线程的 3 种实现方式(内核级,用户级 和 混合型)

    1 .线程的 3 种实现方式 在传统的操作系统中,拥有资源和独立调度的基本单位都是进程.在引入线程的操作系统中,线程是独立调度的基本单位,进程是资源拥有的基本单位.在同一进程中,线程的切换不会引起进程 ...

  7. 用户级线程与内核级线程

    http://blog.csdn.net/yangzl2008/article/details/7014106 在多线程操作系统中,各个系统的实现方式并不相同.在有的系统中实现了用户级线程,有的系统中 ...

  8. 操作系统--用户级线程和内核级线程

    在多线程操作系统中,各个系统的实现方式并不相同.在有的系统中实现了用户级线程,有的系统中实现了内核级线程 1.内核级线程: (1)线程的创建.撤销和切换等,都需要内核直接实现,即内核了解每一个作为可调 ...

  9. 哈工大李治军老师操作系统笔记【10】:内核级线程实现(Learning OS Concepts By Coding Them !)

    文章目录 0 回顾 1 实现 1.1 int 0x80 fork(中断入口) 1.2 进入核心态 1.3 system_call(中断切换中间三段) 1.4 中断出口 1.3 switch_to 1. ...

最新文章

  1. 终于有人把 Python 讲清楚了!
  2. 厉害了!一本正经地为单身狗推荐这个158万张图像的鉴黄数据集
  3. java函数实现进制转换与java实现八进制到十进制的转换(百练OJ:2735:八进制到十进制)
  4. mysql jdbc url设置时区
  5. 面向切面编程--AOP
  6. 信息学奥赛一本通(2044:【例5.12】回文字串)
  7. 成功者都在用的“成功咒语”
  8. 【WPF】设置DataGrid表头内容居中显示
  9. 【265天】跃迁之路——程序员高效学习方法论探索系列(实验阶段23-2017.10.28)...
  10. 七月算法机器学习5 回归分析与工程应用
  11. cas服务器源码,Cas服务端源码解析
  12. 动态规划实战16 leetcode-198. House Robber
  13. 【技巧帖】关于Mac如何内录电脑内部声音
  14. pdffactory字体打印不对_【原创】pdfFactory Pro有关转换PDG图像质量下降解决途径
  15. Windows USB功能驱动开发总结
  16. 虚拟化、文件系统、查找文件
  17. python中pow_Python中float的内置pow()和math.pow()之间的区别?
  18. 华为机试——字符串压缩(stringZip)
  19. 引力波数据居然是用 Python 分析的
  20. 天津少儿编程培训,日本小学生正在把你甩在身后 ​

热门文章

  1. DFAnet:Deep Feature Aggregation for Real-time Semantic Segmentation自己翻译的
  2. VxWorks中文FAQ
  3. 最直白的求婚:老子就想和你上床能咋地?
  4. kali --之 Maltego ce 的使用教程
  5. Linux系列:linux中查看文件时显示行号
  6. MFC中使用sqlite3操作数据库 创建,插入数据,查询数据
  7. Rikka with Travels【换根树dp】
  8. 获取时间段内所有周次及其起讫日期
  9. 内存屏障什么的(经典)
  10. Deep Photo的TensorFlow版本