协作式多任务的功能需求
协作式多任务的主体实现
协作式多任务是一种任务调度方式,它与抢占式多任务(preemptive)相对应,关于后者,我们将在下一章详细说明。在本章学习中,我们先要了解“non-preeptive"——或者说是协作的调度方式。比起抢占,它显得更加友善而不具有侵略性。要设计一个协作式多任务的unikernel,需要满足这些要求:
-
任务切换机制:实现任务的切换和调度,确保多个任务在适当的时候轮流执行。任务切换应该是协作式的,即任务自愿放弃执行权,而不是由系统强制进行切换。这部分的需求确定了unikernel需要依赖于
axtask
这一module以及multitask
、sched_fifo
、sched_cfs
等任务管理相关的crates。 -
上下文保存与恢复:在任务切换时,需要保存当前任务的上下文(包括寄存器、程序计数器、堆栈等状态),以便后续能够正确地恢复该任务的执行状态。这也包括了允许任务在运行过程中主动挂起自己,将执行权让给其他任务。同时,需要提供相应的机制来恢复挂起的任务继续执行。
-
任务优先级管理:支持为不同的任务设置优先级,以确保高优先级的任务在系统资源有限时能够优先得到执行。在ArceOS支持的app中,
apps_priority
实现了这个目标。 -
任务同步与通信:提供机制来实现任务之间的同步和通信,以防止竞态条件和数据访问冲突。在ArceOS中,我们可以参考app
parallel
了解具体的实现。 -
定时器和延时:提供定时器功能,允许任务在一定时间后唤醒或执行延时操作。在ArceOS中,我们可以参考app
sleep
了解具体的实现。
可以感受到,比起Hello World,实现协作式多任务涉及到的modules和crates、调用了它们实现的app都大为增加。
调试和运行需求
在Hello World的实现过程中,我们已经初步了解了ArceOS从代码再到硬件的落地,最后在嵌入式设备实机运行的过程。在本章,读者可以利用上一章的经验,在硬件设备对生成的二进制镜像进行调试。为此,在最终烧录时ArceOS也将实现开发者的调试和改造需求:
-
异常处理:处理任务执行过程中可能出现的异常情况,例如任务错误、内存越界等情况。这些比较难处理的错误需要日志的打印来实现,具体操作我们沿用了HelloWorld中的处理,同时引入了app
exception
细化异常打印日志。 -
系统可扩展性:设计具有良好可扩展性的任务管理机制,允许动态地创建和销毁任务,以适应不同应用场景和任务数量的需求。在实现这个unikernel的app中(
parallel
、priority
、sleep
、yield
),我们都进行了编译内核数、架构、日志输出粒度等的自由设置。
这些功能需求可以根据不同的应用场景和系统设计来进行调整和扩展。实现协作式多任务的关键在于任务的合作和互相信任,确保任务在适当的时机让出执行权,以实现良好的系统响应性和资源利用率。