不知道是不是我工作比较特殊的原因,在我的工作经历中几乎没有什么删除Task的需求。不过,既然这是一个标准性的OS支持功能,还是来掌握一下。
先分析官方例子代码:
任务开始只创建了一个Task1,优先级是1。之后,OS的调度器启动。
在Task1中,打印一个字符串同时创建Task2,优先级是2,之后延迟100ms。这里有一个问题我也很想弄清楚,什么时候能够触发调度?会是系统Tick会触发调度器动作?其实有一个基础的概念我一直没弄清楚,也就是我现在模拟环境下的系统Tick究竟是多少?不过肯定的是,Task2肯定会有机会执行。
Task2的设计算是很特别的,这个任务只执行一次?!没有一个死循环,因此从机理分析看,这个任务打印一个字符串之后,删除了当前任务。这里看得出,这个参数不一定是NULL,还可以是相应的Handle。之后,系统中只剩下了一个Task1,Task1肯定会获得执行机会。
大致分析这么多,先看一下运行效果:
直接感觉上,这个延时绝对不止100ms。从运行效果看,软件执行中Task的执行是交替的,因此从结果上分析,很可能调度器启动后任务的创建或者删除会触发一次任务调度!
增加一个测试,Task1中的delay去掉之后会是什么效果?
运行效果:
软件运行到此,之后不再打印。不知道软件是运行到了什么地方去了?至少不是Task1,如果是屏幕应该还在打印,也不是Task2,不然Task2的信息会被打印出来。增加一个idle hook之后再看,再测试之前先保证了idle hook可以执行。
之后,测试之前的软件,效果依然类似。也就是说,有一个Task应该吧idle task给饿死了。或者直接进入了某个故障状态。
接下来,用了我不熟悉的VS断点调试发现,其实这个问题是因为heap空间被消耗完了。为了验证,我扩大了heap的大小。之后,测试效果如下:
这个截图中出现了多次任务切换,但是,最终还是卡死了。但是可以看得出调度上的一个改进了,也在一定程度上验证了我自己的猜测。