10、用户级线程:指令的切换

为什么先讲线程?因为线程切换是只有指令序列(PC指针)在切换,加上内存切换才是进程的切换。这是从简入繁的顺序 。

1、用户级线程:用户主动切换线程
进程 = 资源 + 指令执行序列
线程保留了并发的有点,避免了进程切换的代价。

指令序列在切换的时候,需要切换PCB中记录的信息,寄存器等。能不能不切换内存映射表(寄存器还是得切换的)?答案是可以的,这就是用户级线程所做的事情。将资源和指令执行分开,一个资源+多个指令执行序列。
举个例子:一个浏览器需要从网上下载数据,需要显示文字,需要解压图片,这些不同的任务实际上都需要共享数据,没必要将数据保存在不同地方,所以很适合使用多线程设计。
使用create创建线程,主动调用yield切换线程。create是制造出第一次切换时应该的样子,yield是知道切换时需要是什么样子。
在这里插入图片描述
在这里插入图片描述

2、yield函数:切换栈
yield函数遇到什么问题:指令切换时,常常会将下一条指令压栈,以便后续恢复现场。但是对于多线程而言,不能共用一个栈,因为跳到别的线程执行的时候,会污染原来的程序栈导致无法返回正确的下一条指令。、
在这里插入图片描述

怎么解决:不同线程用不同的指令栈TCB,一个TCB关联一个用户栈,TCB切换引起用户栈切换(因为TCB中的esp记录的是栈的位置)。Yield函数先保护现场,将esp放在当前TCB中,用Next进行调度,从下一个TCB中取出esp,切换栈。使用全局栈指针esp,记录当前正在使用的栈指针,切换的时候,把当前栈指针保存到TCB中,到时候从中恢复。
为什么这样解决:最关键的地方在于,yield为什么不需要指定切换完之后要执行的下一条PC指令?⭐⭐⭐⭐⭐⭐
因为栈中的下一条PC指令是在调用yield时压进去的,别的进程调用yield之后,遇到函数的 },就会自动从栈中弹出一条指令。只要我在程序的 }之前完成了栈的切换, }之后就会自动弹出之前被压进去的下一条PC指令。根据这样的设计,线程的初始化只要在线程的初始化栈中事先存进这个线程的第一条PC指令(起始地址),那么在第一次由yield切换到这个线程时,yield的 }会自动将这个新线程中弹出这个被我们存进的第一条PC指令,开始运行新的线程。

在这里插入图片描述

3、ThreadCreate():做出两个TCB、两个栈、待切换到PC存在栈中
申请栈、申请TCB、将起始地址等压入栈中、关联TCB和栈
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值