RTOS操作系统多线程抢占的工作原理
关注+星标公众号,不错过精彩内容
作者 | strongerHuang
微信公众号 | 嵌入式专栏
最近看见技术交流群在讨论相关的问题,这里分享一篇旧文,希望对这部分读者有帮助。
线程基础原理
线程之间抢占
中断抢占线程
中断抢占中断
嵌入式专栏
1
1.单核“单线程”
严格来说,单核处理器一次只能执行一条指令,也就是说只能“单线程”。(当然,多核处理器就不一样)
为了在单核处理器上运行多个线程,我们实际上需要定期在线程之间进行快速切换,以便用户感觉多个线程在并行运行。
比如处理器执行两个线程,处理器实际在两个线程之间来回切换,如下图:
2.处理器在线程之间切换,它是如何做到的?
我们说的单核处理器是“单线程”的,它有一组寄存器,我们就叫这组寄存器属于一个“线程”。
例如,计算两个数字的总和时:
//假设我们有两个整数:a和b
int c = a + b ;
实际发生的情况如下所示(当然,它取决于的MCU类型,但总体思路是相同):
# MIPS反汇编:
LW V0, -32744(GP) # "a" 的值从RAM加载到寄存器V0
LW V1, -32740(GP) # 值"b" 从RAM加载到寄存器V1
ADDU V0, V1, V0 # a、b值相加,结果保存到寄存器V0中
SW V0, -32496(GP) # 寄存器V0的值存储在RAM中(变量c所在的位置)
你会发现上面执行了4个动作,但是抢占式操作系统可以在任何时候抢占另一个线程,包括在这4个动作之间。
假如在这过程中有其他线程抢占了,其他线程同样抢占了当前线程V0、 V1,如果不对V0、 V1进行保存,那么下次回来执行当前线程,结果就会出错。
所以,针对当前这种问题,我们就需要在切换线程之前,对V0、 V1的数值进行保存,当下次切换到当前线程,再恢复V0、 V1的数值,大致流程如下:
大概意思就是:当我们需要从一个线程切换到另一个线程时,内核获得控制权,执行必要的内务处理(至少要保存和恢复寄存器值),然后将控制权转移到下一个线程以运行。
嵌入式专栏
2
将所有寄存器值保存到堆栈中(保存到线程A堆栈的顶部);
将堆栈指针切换到线程B的堆栈顶部;
从堆栈(从线程B的堆栈顶部)恢复所有寄存器值;
嵌入式专栏
3
嵌入式专栏
3
使用被中断的线程堆栈;
为中断使用单独的堆栈空间;
线程自己的数据;
线程的上下文;
用于执行最坏情况的ISR的数据。
后台回复『RTOS』『操作系统』阅读更多相关文章。
点击“阅读原文”查看更多分享,欢迎点分享、收藏、点赞、在看。