本文内容为自己学习OpenHarmony中LiteOS的学习笔记及心得,因本人能力有限,内容或有错漏,请多包涵。本文会反复修正,持续更新。
小故事之奇葩打印机构(进程篇)
该小故事用来记录我的学习进度,会持续更新及更正。该小故事以LiteOS-a的运行为主线。
小张创办了一家打印机构,买下了一整层楼作为大本营,并买了一台能打印、复印、彩印等多功能的打印机(CPU)放在打印间。
1、进程模块初始化
首先,小张把所有办公室(进程地址空间)都清空,等待各个项目组入驻,并给1号房间贴上“项目管理组”的标签 ,2号房间贴上了“核心管理组”的标签。
^小张这步做的在LiteOS中相当于将进程模块初始化,其中先将进程池清空,然后给1、2号进程分别贴上标签,表示这两个进程现在虽然为空,但后续会分别设置为用户模式的根进程(Init)和内核模式的根进程(KProcess)。
然后,小张邀请核心管理组入驻办公室。核心管理组不需要负责项目,只需要处理一些重要文件。在核心管理组入住后,组内讨论决定新增一个设备维护组,办公室为0号房间。其任务为,在没有人使用打印机时,负责保养和维护打印机。
小张将核心管理组安排好后,将项目管理组也邀请了过来。项目管理组主要负责各种项目的申请和审批,其中包括打印、复印、彩印等。
^KProcess具有最高的优先级0级,会长期活跃地跑一些重要任务,其创建好后,通过fork得到内核态的第二个进程Kdle,其为0号进程,只负责在CPU空闲时收留CPU。
Init优先级较低(具体原因我目前还不了解),主要负责用户态进程的创建。
2、进程运行
小张的打印机构很奇怪,除了核心管理组、项目管理组和设备管理组,其他员工都不是长期雇佣的,而是按项目招聘兼职员工,一个项目做完后,员工合同就到期了。
小张将创建机构的一些杂事打理好后,机构开始正常运转。第一天,小张接到了第一批打印订单,然后他招聘了一个项目负责人。负责人开始向项目管理组申请打印项目和项目办公间,项目申请成功后,因为只有打印任务,所以项目负责人认为自己一个人就能完成,所以就废寝忘食地使用打印机打印。当他打印完后,向项目管理组报告,然后项目管理组结算项目并回收办公间。
^用户态进程的创建需要从用户模式的根进程(Init)clone,每个进程至少有一个Task,对应小故事每个项目至少有一个人工作,而当进程结束后,父进程会将其进程资源回收。这是单进程模式下的运行。
过了几天小张的打印机构机构同时来了两位顾客,一位要彩印一批文件,一位要复印一批文件。小张为此招聘了两个项目组,分别负责这两个项目,并让两位顾客在接待区等候。
但小张也因此遇到了一些困难,同时接到了两个项目,但只有一台打印机,同一时间只能进行一个项目,而且虽然顾客看不到具体打印过程,但能打印出来的成品是摆放在公共区域的,这个区域顾客是可以观看的。如果先打印其中一个项目,然后再打印另一个,会不会让后拿到的顾客不开心?
为此,小张想出了两种解决方案。方案一,再购买一台打印机,这样两个项目就能同时进行了。方案二,每隔一小段时间,就换一个项目使用打印机,那么顾客每隔一段时间看一次成品摆放区域,总能看到同时产出两个项目的成果,那么顾客在不知道具体打印过程的情况下,就会认为两个项目在同时进行。
^当需要同时运行多个进程时,小故事中方案一对应的就是多核CPU的处理方法,这样能实现进程的并行。而只有单核时,为了让多个进程达到同时运行的效果,就要让进程运行一小段时间后,记录下当前状态,假设为A点,然后切换至第二个进程;当第二个进程运行一小段时间后,也需要记录当前运行状态,然后再次切换任务。如果只有两个进程,那么第二个进程切换后,就会回到第一个进程的A点,然后继续往后运行,并以此不断循环,至进程结束。这在微观上看,进程还是串行运行的,但从宏观上看,每一大段时间,都会有多个进程在运行,由此这些进程可以看做是并发的。
因为方案一不能马上解决当前问题,所以小张使用了方案二。他找来一个沙漏,并告诉员工,今后在多个项目同时需要打印机时,每个项目每次只能使用20次沙漏的时间,时间到后,需要将打印机交给下一个项目组,然后一直循环。
^为了规范任务的执行,操作系统中有了时钟节拍的概念,即时钟节拍是操作系统中的最小时间单位(Tick),在小故事中,一个沙漏即为一个Tick。而进程的切换也需要按照一定的时间规律,而这个时间规律即为时间片,每个进程都拥有自己的时间片,当时间片用完时,就要将CPU让给其他准备好的进程。在小故事中,每个时间片对应2个沙漏时间,所以每个项目(进程)用完10个时间片后,就要将打印机(CPU)让给其他项目(进程)。