1# 任务<a name="ZH-CN_TOPIC_0000001078641280"></a> 2 3- [基本概念](#section138411646175417) 4- [运行机制](#section1381918945512) 5- [开发指导](#section10649727135519) 6 - [接口说明](#section78333315555) 7 - [开发流程](#section16229657115514) 8 - [编程实例](#section2809723165612) 9 10 11## 基本概念<a name="section138411646175417"></a> 12 13从系统的角度看,任务Task是竞争系统资源的最小运行单元。任务可以使用或等待CPU、使用内存空间等系统资源,并独立于其它任务运行。 14 15OpenHarmony 内核中使用一个任务表示一个线程。 16 17OpenHarmony 内核中同优先级进程内的任务统一调度、运行。 18 19OpenHarmony 内核中的任务采用抢占式调度机制,同时支持时间片轮转调度和FIFO调度方式。 20 21OpenHarmony 内核的任务一共有32个优先级\(0-31\),最高优先级为0,最低优先级为31。 22 23当前进程内, 高优先级的任务可抢占低优先级任务,低优先级任务必须在高优先级任务阻塞或结束后才能得到调度。 24 25**任务状态说明**: 26 27- 初始化(Init):任务正在被创建。 28 29- 就绪(Ready):任务在就绪列表中,等待CPU调度。 30- 运行(Running):任务正在运行。 31- 阻塞(Blocked):任务被阻塞挂起。Blocked状态包括:pending\(因为锁、事件、信号量等阻塞\)、suspended(主动pend)、delay\(延时阻塞\)、pendtime\(因为锁、事件、信号量时间等超时等待\)。 32- 退出(Exit):任务运行结束,等待父任务回收其控制块资源。 33 34**图 1** 任务状态迁移示意图<a name="fig5251243193113"></a> 35 36 37**任务状态迁移说明:** 38 39- Init→Ready: 40 41 任务创建拿到控制块后为初始化阶段\(Init状态\),当任务初始化完成将任务插入调度队列,此时任务进入就绪状态。 42 43- Ready→Running: 44 45 任务创建后进入就绪态,发生任务切换时,就绪列表中最高优先级的任务被执行,从而进入运行态,此刻该任务从就绪列表中删除。 46 47- Running→Blocked: 48 49 正在运行的任务发生阻塞(挂起、延时、读信号量等)时,任务状态由运行态变成阻塞态,然后发生任务切换,运行就绪列表中剩余最高优先级任务。 50 51- Blocked→Ready : 52 53 阻塞的任务被恢复后(任务恢复、延时时间超时、读信号量超时或读到信号量等),此时被恢复的任务会被加入就绪列表,从而由阻塞态变成就绪态。 54 55- Ready→Blocked: 56 57 任务也有可能在就绪态时被阻塞(挂起),此时任务状态会由就绪态转变为阻塞态,该任务从就绪列表中删除,不会参与任务调度,直到该任务被恢复。 58 59- Running→Ready: 60 61 有更高优先级任务创建或者恢复后,会发生任务调度,此刻就绪列表中最高优先级任务变为运行态,那么原先运行的任务由运行态变为就绪态,并加入就绪列表中。 62 63- Running→Exit: 64 65 运行中的任务运行结束,任务状态由运行态变为退出态。若为设置了分离属性(LOS\_TASK\_STATUS\_DETACHED)的任务,运行结束后将直接销毁。 66 67 68## 运行机制<a name="section1381918945512"></a> 69 70OpenHarmony 任务管理模块提供任务创建、任务延时、任务挂起和任务恢复、锁任务调度和解锁任务调度、根据ID查询任务控制块信息功能。 71 72用户创建任务时,系统会将任务栈进行初始化,预置上下文。此外,系统还会将“任务入口函数”地址放在相应位置。这样在任务第一次启动进入运行态时,将会执行任务入口函数。 73 74## 开发指导<a name="section10649727135519"></a> 75 76### 接口说明<a name="section78333315555"></a> 77 78<a name="table687929113814"></a> 79<table><thead align="left"><tr id="row513082983812"><th class="cellrowborder" valign="top" width="33.33333333333333%" id="mcps1.1.4.1.1"><p id="p121309298384"><a name="p121309298384"></a><a name="p121309298384"></a>功能分类</p> 80</th> 81<th class="cellrowborder" valign="top" width="33.33333333333333%" id="mcps1.1.4.1.2"><p id="p713082933817"><a name="p713082933817"></a><a name="p713082933817"></a>接口<strong id="b197068338312"><a name="b197068338312"></a><a name="b197068338312"></a>名称</strong></p> 82</th> 83<th class="cellrowborder" valign="top" width="33.33333333333333%" id="mcps1.1.4.1.3"><p id="p20130829123810"><a name="p20130829123810"></a><a name="p20130829123810"></a>描述</p> 84</th> 85</tr> 86</thead> 87<tbody><tr id="row713032973813"><td class="cellrowborder" rowspan="3" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.1 "><p id="p0130429133818"><a name="p0130429133818"></a><a name="p0130429133818"></a>任务的创建和删除</p> 88</td> 89<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.2 "><p id="p6130102911384"><a name="p6130102911384"></a><a name="p6130102911384"></a>LOS_TaskCreateOnly</p> 90</td> 91<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.3 "><p id="p181303297387"><a name="p181303297387"></a><a name="p181303297387"></a>创建任务,并使该任务进入Init状态,不执行任务调度</p> 92</td> 93</tr> 94<tr id="row51301329123813"><td class="cellrowborder" valign="top" headers="mcps1.1.4.1.1 "><p id="p41301293386"><a name="p41301293386"></a><a name="p41301293386"></a>LOS_TaskCreate</p> 95</td> 96<td class="cellrowborder" valign="top" headers="mcps1.1.4.1.2 "><p id="p513092983812"><a name="p513092983812"></a><a name="p513092983812"></a>创建任务,并使该任务进入Ready状态,并调度</p> 97</td> 98</tr> 99<tr id="row14130729193816"><td class="cellrowborder" valign="top" headers="mcps1.1.4.1.1 "><p id="p7130152993810"><a name="p7130152993810"></a><a name="p7130152993810"></a>LOS_TaskDelete</p> 100</td> 101<td class="cellrowborder" valign="top" headers="mcps1.1.4.1.2 "><p id="p11130122910387"><a name="p11130122910387"></a><a name="p11130122910387"></a>删除指定的任务</p> 102</td> 103</tr> 104<tr id="row1513118292383"><td class="cellrowborder" rowspan="4" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.1 "><p id="p1813114299384"><a name="p1813114299384"></a><a name="p1813114299384"></a>任务状态控制</p> 105</td> 106<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.2 "><p id="p1713113291382"><a name="p1713113291382"></a><a name="p1713113291382"></a>LOS_TaskResume</p> 107</td> 108<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.3 "><p id="p16131229173819"><a name="p16131229173819"></a><a name="p16131229173819"></a>恢复挂起的任务</p> 109</td> 110</tr> 111<tr id="row9131729173817"><td class="cellrowborder" valign="top" headers="mcps1.1.4.1.1 "><p id="p131311929123810"><a name="p131311929123810"></a><a name="p131311929123810"></a>LOS_TaskSuspend</p> 112</td> 113<td class="cellrowborder" valign="top" headers="mcps1.1.4.1.2 "><p id="p1813192919384"><a name="p1813192919384"></a><a name="p1813192919384"></a>挂起指定的任务</p> 114</td> 115</tr> 116<tr id="row151311929193818"><td class="cellrowborder" valign="top" headers="mcps1.1.4.1.1 "><p id="p213114299387"><a name="p213114299387"></a><a name="p213114299387"></a>LOS_TaskDelay</p> 117</td> 118<td class="cellrowborder" valign="top" headers="mcps1.1.4.1.2 "><p id="p141311729183817"><a name="p141311729183817"></a><a name="p141311729183817"></a>任务延时等待</p> 119</td> 120</tr> 121<tr id="row18131182910384"><td class="cellrowborder" valign="top" headers="mcps1.1.4.1.1 "><p id="p15131122923810"><a name="p15131122923810"></a><a name="p15131122923810"></a>LOS_TaskYield</p> 122</td> 123<td class="cellrowborder" valign="top" headers="mcps1.1.4.1.2 "><p id="p1713122953816"><a name="p1713122953816"></a><a name="p1713122953816"></a>显式放权,调整调用任务优先级的任务调度顺序</p> 124</td> 125</tr> 126<tr id="row9131829123812"><td class="cellrowborder" rowspan="2" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.1 "><p id="p1313115299387"><a name="p1313115299387"></a><a name="p1313115299387"></a>任务调度的控制</p> 127</td> 128<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.2 "><p id="p101312029113815"><a name="p101312029113815"></a><a name="p101312029113815"></a>LOS_TaskLock</p> 129</td> 130<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.3 "><p id="p0131629183812"><a name="p0131629183812"></a><a name="p0131629183812"></a>锁任务调度</p> 131</td> 132</tr> 133<tr id="row5131829193813"><td class="cellrowborder" valign="top" headers="mcps1.1.4.1.1 "><p id="p1313182910388"><a name="p1313182910388"></a><a name="p1313182910388"></a>LOS_TaskUnlock</p> 134</td> 135<td class="cellrowborder" valign="top" headers="mcps1.1.4.1.2 "><p id="p1131122913812"><a name="p1131122913812"></a><a name="p1131122913812"></a>解锁任务调度</p> 136</td> 137</tr> 138<tr id="row213115292389"><td class="cellrowborder" rowspan="3" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.1 "><p id="p41312295381"><a name="p41312295381"></a><a name="p41312295381"></a>任务优先级的控制</p> 139</td> 140<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.2 "><p id="p1131829103815"><a name="p1131829103815"></a><a name="p1131829103815"></a>LOS_CurTaskPriSet</p> 141</td> 142<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.3 "><p id="p6131729163810"><a name="p6131729163810"></a><a name="p6131729163810"></a>设置当前任务的优先级</p> 143</td> 144</tr> 145<tr id="row913142917389"><td class="cellrowborder" valign="top" headers="mcps1.1.4.1.1 "><p id="p10131172913819"><a name="p10131172913819"></a><a name="p10131172913819"></a>LOS_TaskPriSet</p> 146</td> 147<td class="cellrowborder" valign="top" headers="mcps1.1.4.1.2 "><p id="p113162912387"><a name="p113162912387"></a><a name="p113162912387"></a>设置指定任务的优先级</p> 148</td> 149</tr> 150<tr id="row7131192913812"><td class="cellrowborder" valign="top" headers="mcps1.1.4.1.1 "><p id="p713142923817"><a name="p713142923817"></a><a name="p713142923817"></a>LOS_TaskPriGet</p> 151</td> 152<td class="cellrowborder" valign="top" headers="mcps1.1.4.1.2 "><p id="p14131162923818"><a name="p14131162923818"></a><a name="p14131162923818"></a>获取指定任务的优先级</p> 153</td> 154</tr> 155<tr id="row14132329133817"><td class="cellrowborder" rowspan="2" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.1 "><p id="p81323295380"><a name="p81323295380"></a><a name="p81323295380"></a>任务信息获取</p> 156</td> 157<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.2 "><p id="p31324294389"><a name="p31324294389"></a><a name="p31324294389"></a>LOS_CurTaskIDGet</p> 158</td> 159<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.3 "><p id="p14132929193814"><a name="p14132929193814"></a><a name="p14132929193814"></a>获取当前任务的ID</p> 160</td> 161</tr> 162<tr id="row4132182920383"><td class="cellrowborder" valign="top" headers="mcps1.1.4.1.1 "><p id="p15133172923815"><a name="p15133172923815"></a><a name="p15133172923815"></a>LOS_TaskInfoGet</p> 163</td> 164<td class="cellrowborder" valign="top" headers="mcps1.1.4.1.2 "><p id="p5133329123814"><a name="p5133329123814"></a><a name="p5133329123814"></a>获取指定任务的信息</p> 165</td> 166</tr> 167<tr id="row855810357401"><td class="cellrowborder" rowspan="2" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.1 "><p id="p9682331164117"><a name="p9682331164117"></a><a name="p9682331164117"></a>任务绑核操作</p> 168</td> 169<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.2 "><p id="p205581835144010"><a name="p205581835144010"></a><a name="p205581835144010"></a>LOS_TaskCpuAffiSet</p> 170</td> 171<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.3 "><p id="p115582035154014"><a name="p115582035154014"></a><a name="p115582035154014"></a>绑定指定任务到指定cpu上运行,仅在多核下使用</p> 172</td> 173</tr> 174<tr id="row5866193714018"><td class="cellrowborder" valign="top" headers="mcps1.1.4.1.1 "><p id="p8867133744011"><a name="p8867133744011"></a><a name="p8867133744011"></a>LOS_TaskCpuAffiGet</p> 175</td> 176<td class="cellrowborder" valign="top" headers="mcps1.1.4.1.2 "><p id="p10867173718404"><a name="p10867173718404"></a><a name="p10867173718404"></a>获取指定任务的绑核信息,仅在多核下使用</p> 177</td> 178</tr> 179<tr id="row197312218434"><td class="cellrowborder" rowspan="2" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.1 "><p id="p20362114474318"><a name="p20362114474318"></a><a name="p20362114474318"></a>任务调度参数的控制</p> 180</td> 181<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.2 "><p id="p5974192215434"><a name="p5974192215434"></a><a name="p5974192215434"></a>LOS_GetTaskScheduler</p> 182</td> 183<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.3 "><p id="p2974922164317"><a name="p2974922164317"></a><a name="p2974922164317"></a>获取指定任务的调度策略</p> 184</td> 185</tr> 186<tr id="row141414214436"><td class="cellrowborder" valign="top" headers="mcps1.1.4.1.1 "><p id="p9141202144319"><a name="p9141202144319"></a><a name="p9141202144319"></a>LOS_SetTaskScheduler</p> 187</td> 188<td class="cellrowborder" valign="top" headers="mcps1.1.4.1.2 "><p id="p3141221154319"><a name="p3141221154319"></a><a name="p3141221154319"></a>设置指定任务的调度参数,包括优先级和调度策略</p> 189</td> 190</tr> 191<tr id="row617914918441"><td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.1 "><p id="p17180184911445"><a name="p17180184911445"></a><a name="p17180184911445"></a>系统支持的最大任务数</p> 192</td> 193<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.2 "><p id="p151807498449"><a name="p151807498449"></a><a name="p151807498449"></a>LOS_GetSystemTaskMaximum</p> 194</td> 195<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.3 "><p id="p81801249124417"><a name="p81801249124417"></a><a name="p81801249124417"></a>获取系统支持的最大任务数目</p> 196</td> 197</tr> 198</tbody> 199</table> 200 201### 开发流程<a name="section16229657115514"></a> 202 203任务的典型开发流程: 204 2051. 通过LOS\_TaskCreate创建一个任务。 206 - 指定任务的执行入口函数 207 208 - 指定任务名 209 - 指定任务的栈大小 210 - 指定任务的优先级 211 - 指定任务的属性,是否支持LOS\_TASK\_STATUS\_DETACHED属性 212 - 多核运行时,可以选择设置任务的绑核属性 213 2142. 任务参与调度运行,执行用户指定的业务代码。 2153. 任务执行结束,如果任务设置了LOS\_TASK\_STATUS\_DETACHED属性,则任务运行结束后自动回收任务资源,如果未设置LOS\_TASK\_STATUS\_DETACHED属性,则需要调用LOS\_TaskDelete接口回收任务资源。 216 217> **说明:** 218>- 内核态具有最高权限,可以操作任意进程内的任务。 219>- 用户态进程通过系统调用进入内核态后创建的任务属于KProcess, 不属于当前用户态进程。 220 221### 编程实例<a name="section2809723165612"></a> 222 223代码实现如下: 224 225``` 226UINT32 g_taskLoID; 227UINT32 g_taskHiID; 228#define TSK_PRIOR_HI 4 229#define TSK_PRIOR_LO 5 230UINT32 ExampleTaskHi(VOID) 231{ 232 UINT32 ret; 233 PRINTK("Enter TaskHi Handler.\n"); 234 /* 延时2个Tick,延时后该任务会挂起,执行剩余任务中最高优先级的任务(g_taskLoID任务) */ 235 ret = LOS_TaskDelay(2); 236 if (ret != LOS_OK) { 237 PRINTK("Delay Task Failed.\n"); 238 return LOS_NOK; 239 } 240 /* 2个Tick时间到了后,该任务恢复,继续执行 */ 241 PRINTK("TaskHi LOS_TaskDelay Done.\n"); 242 /* 挂起自身任务 */ 243 ret = LOS_TaskSuspend(g_taskHiID); 244 if (ret != LOS_OK) { 245 PRINTK("Suspend TaskHi Failed.\n"); 246 return LOS_NOK; 247 } 248 PRINTK("TaskHi LOS_TaskResume Success.\n"); 249 return LOS_OK; 250} 251 252/* 低优先级任务入口函数 */ 253UINT32 ExampleTaskLo(VOID) 254{ 255 UINT32 ret; 256 PRINTK("Enter TaskLo Handler.\n"); 257 /* 延时2个Tick,延时后该任务会挂起,执行剩余任务中就高优先级的任务(背景任务) */ 258 ret = LOS_TaskDelay(2); 259 if (ret != LOS_OK) { 260 PRINTK("Delay TaskLo Failed.\n"); 261 return LOS_NOK; 262 } 263 PRINTK("TaskHi LOS_TaskSuspend Success.\n"); 264 /* 恢复被挂起的任务g_taskHiID */ 265 ret = LOS_TaskResume(g_taskHiID); 266 if (ret != LOS_OK) { 267 PRINTK("Resume TaskHi Failed.\n"); 268 return LOS_NOK; 269 } 270 PRINTK("TaskHi LOS_TaskDelete Success.\n"); 271 return LOS_OK; 272} 273/* 任务测试入口函数,在里面创建优先级不一样的两个任务 */ 274UINT32 ExampleTaskCaseEntry(VOID) 275{ 276 UINT32 ret; 277 TSK_INIT_PARAM_S initParam = {0}; 278 279 /* 锁任务调度 */ 280 LOS_TaskLock(); 281 PRINTK("LOS_TaskLock() Success!\n"); 282 initParam.pfnTaskEntry = (TSK_ENTRY_FUNC)ExampleTaskHi; 283 initParam.usTaskPrio = TSK_PRIOR_HI; 284 initParam.pcName = "HIGH_NAME"; 285 initParam.uwStackSize = LOS_TASK_MIN_STACK_SIZE; 286 initParam.uwResved = LOS_TASK_STATUS_DETACHED; 287 288 /* 创建高优先级任务,由于锁任务调度,任务创建成功后不会马上执行 */ 289 ret = LOS_TaskCreate(&g_taskHiID, &initParam); 290 if (ret != LOS_OK) { 291 LOS_TaskUnlock(); 292 PRINTK("ExampleTaskHi create Failed! ret=%d\n", ret); 293 return LOS_NOK; 294 } 295 PRINTK("ExampleTaskHi create Success!\n"); 296 297 initParam.pfnTaskEntry = (TSK_ENTRY_FUNC)ExampleTaskLo; 298 initParam.usTaskPrio = TSK_PRIOR_LO; 299 initParam.pcName = "LOW_NAME"; 300 initParam.uwStackSize = LOS_TASK_MIN_STACK_SIZE; 301 initParam.uwResved = LOS_TASK_STATUS_DETACHED; 302 303 /* 创建低优先级任务,由于锁任务调度,任务创建成功后不会马上执行 */ 304 ret = LOS_TaskCreate(&g_taskLoID, &initParam); 305 if (ret!= LOS_OK) { 306 LOS_TaskUnlock(); 307 PRINTK("ExampleTaskLo create Failed!\n"); 308 return LOS_NOK; 309 } 310 PRINTK("ExampleTaskLo create Success!\n"); 311 312 /* 解锁任务调度,此时会发生任务调度,执行就绪列表中最高优先级任务 */ 313 LOS_TaskUnlock(); 314 315 while(1){}; 316 return LOS_OK; 317} 318``` 319 320编译运行得到的结果为: 321 322``` 323LOS_TaskLock() Success! 324ExampleTaskHi create Success! 325ExampleTaskLo create Success! 326Enter TaskHi Handler. 327Enter TaskLo Handler. 328TaskHi LOS_TaskDelay Done. 329TaskHi LOS_TaskSuspend Success. 330TaskHi LOS_TaskResume Success. 331TaskHi LOS_TaskDelete Success. 332``` 333 334