对于学习,我有一个观点,便是学习一项技能,就要学习它的历史,这样才能搞清楚他的来龙去脉,理解他当下为什么是这个样子。
对于嵌入式编程来讲更是这样,单片机性能相当于早期的计算机,嵌入式程序员所面临的环境相当于早期的计算机程序员。我们可以从那里获得较好的经验。
在前面,我们探讨了回调和协程两种并发模型。对于复杂程序,回调模型实现困难,可读性不高,为此我们引入了协程模型。
我们还是沿用上一节的例子,对于一个LED,先点亮3s,再熄灭5s,然后点亮5s,再熄灭3s。我们希望得到的代码是样的
void LedFlash()
{
LedOn();
delay(3);
LedOff();
delay(5);
LedOn();
delay(5);
LedOff();
delay(3);
}
在上一节,我们利用协程模型得到了这样的代码
void LedFlash()
{
Begin();
LedOn();
setTimerEvent(3000,LedFlash); //定时3s,3s后定时器系统再调用LedFlash函数
Yield(); //yield,让出CPU,对应代码我们可以看到是return返回
LedOff(); //3s后,LedFlash函数会根据state直接执行这一行
setTimerEvent(5000,LedFlash);
Yield(); //yield,让出CPU
LedOn();
setTimerEvent(5000,LedFlash);
Yield(); //yield,让出CPU
LedOff();
setTimerEvent(3000,LedFlash);
Yield(); //yield,让出CPU
End();
}
对比两段代码,我们会发现,协程模型多了Begin、setTimerEvent、Yield、End
等函数语义。
同时,我们可以观察到,线程模型的delay
函数实现了Yield、setTimerEvent
语义。
也就是说,delay
函数,让出了CPU,并会在定时结束后,自动回到该函数继续执行。这是怎样实现的呢?
void delay(int ms){
setTimerEvent(ms,LedFlash); //delay函数需要‘记得’在延时到期后执行delay后的语句
Yield(); //yield,让出CPU //让出CPU,协程模型时我们是用的return呢?
}
- delay函数需要‘记得’在延时到期后执行delay后的语句,这应该怎样实现呢?
- 让出CPU,在协程模型中我们用的return,可在这里应该怎样实现呢?
我们再单片机的C语言一节中,讲述了单片机的C语言模型。这里我们再回忆一遍。
- 单片机上有PC寄存器,记录指令地址,用于取指,有SP寄存器用于记录栈。
- CPU在执行指令期间,会产生一些临时数据,一般都放置在栈,堆、bss空间。
- 我们把上述CPU执行过程中用到的资源,称作运行上下文。
这样我们便可以得到一个结构体,记录上下文
struct context{
int pc;
int sp;
void *begin_bss;
void *end_bss;
void *heap;
....
};
- 需要有一个当前上下文
struct context *current
,记录当前执行序列的栈,堆,bss段等空间 - 一个线程便是一个指令执行序列,需要一个上下文
- 线程切换,便是将就绪线程的上下文机构,赋值给当前上下文结构,然后,执行PC跳转。
-
struct context
相当于模拟了单片机的寄存器,内存等基本硬件。一个结构对应一套资源,只不过缺少CPU,对于CPU的复用,得从时间上来看,1ms执行序列(线程)A,1ms执行序列(线程)B,这样对于1s这个时段来说,A、B是同时执行的,他们共享了CPU。 - 上下文切换需要对相当多的内容进行赋值,消耗是比较大的。
void delay(int ms){
Yield(); //这里可以是 线程切换
setTimerEvent(ms,LedFlash); //再切换后来时,PC指针记录了当前位置,知道该执行哪条指令
delay函数让出了CPU,这是一个主动过程,对于多线程来讲,任务切换是需要调度器的。
- 调度器后台执行,记录所有线程。
- 利用定时器,实现一个100ms的定时器,我们称为时钟滴答,定时到了,遍历所有线程,检测该执行哪一个。
- delay这类函数,会主动让出CPU,完成任务切换
- 调度器,会根据某个线程的执行时间,优先级来对其进行调度。强制完成线程切换。
到这里,我们还有一个东西没有说,便是线程的同步。不过根据这篇文章,你应该对线程有了一个基本的认识,线程同步是个复杂的问题,需要的是更多的思考和练习,这里便不多做介绍了。
这是一个免费,开源的教程,如果你喜欢可以转发,也可以打赏奖励。 欢迎关注微信公众号小站练兵
网友评论