Skip to content

时间中断

CPU的时钟每隔一段时间都会产生一个中断,这样内核就可以利用这个中断信号实现多个进程间的时间分片(time-slice)。时间中断的频率通常是每秒100次,这样即可以保证舒适的交互效果又不至于频繁的中断影响CPU的运行。

时间中断的流程

遵循中断处理的流程,时间中断也会进入trap函数,在这里针对时间中断实现了两个功能,一个是实现ticks计数唤醒之前sleep的进程,另一个是调用yield让出CPU给其他进程使用。这里重点关注关于时间分片的实现,所以只分析第二个功能。

追踪yield的调用轨迹依次进入 yield()-> sched() --> swtch(&p->context, mycpu()->scheduler),关于swtch的具体分析在"CPU调度线程"那里已经作过描述。这里的mycpu()->scheduler就是上一次在scheduler()调用swtch让出CPU给当下这个进程并把自己的寄存器保存的位置。这里再次调用swtch 只是参数的顺序与上一次正好相反,CPU调度线程(mycpu()->scheduler)被换入,进程(p->context)被换出。这里的swtch执行完成后,当前进程让出CPU停止运行,scheduler重新获得CPU接着上次停止的地方继续运行,寻找下一个可以运行的进程。后面的某一个时刻scheduler也会再次选中当前停止的进程再次恢复它的运行。当被恢复的时候,当前进程接着上次中止的地方也就是调用swtch的地方的继续执行,按之前“yield”的调用轨迹相反的方向依次返回,最后调用trapret返回到被“时间中断”中断的位置继续执行。

从上面的可以看出sched() 和 scheduler() 相互协作,像这样的两个函数被称为“coroutines”。