鸿蒙内核源码分析(任务调度篇) | 任务是内核调度的单元

本文为博客 VIP 文章,开通 VIP 后可阅读全文

开通 VIP

任务即线程

在鸿蒙内核中,广义上可理解为一个任务就是一个线程

官方是怎么描述线程的

基本概念
从系统的角度看,线程是竞争系统资源的最小运行单元。线程可以使用或等待CPU、使用内存空间等系统资源,并独立于其它线程运行。

鸿蒙内核每个进程内的线程独立运行、独立调度,当前进程内线程的调度不受其它进程内线程的影响。

鸿蒙内核中的线程采用抢占式调度机制,同时支持时间片轮转调度和FIFO调度方式。

鸿蒙内核的线程一共有32个优先级(0-31),最高优先级为0,最低优先级为31。

当前进程内高优先级的线程可抢占当前进程内低优先级线程,当前进程内低优先级线程必须在当前进程内高优先级线程阻塞或结束后才能得到调度。

线程状态说明:

初始化(Init):该线程正在被创建。

就绪(Ready):该线程在就绪列表中,等待CPU调度。

运行(Running):该线程正在运行。

阻塞(Blocked):该线程被阻塞挂起。Blocked状态包括:pend(因为锁、事件、信号量等阻塞)、suspend(主动pend)、delay(延时阻塞)、pendtime(因为锁、事件、信号量时间等超时等待)。

退出(Exit):该线程运行结束,等待父线程回收其控制块资源。

图 1 线程状态迁移示意图

注意官方文档说的是线程,没有提到task(任务),但内核源码中却有大量 task代码,很少有线程(thread)代码 ,这是怎么回事?
其实在鸿蒙内核中, task就是线程, 初学者完全可以这么理解,但二者还是有区别,否则干嘛要分两个词描述。
会有什么区别?是管理上的区别,task是调度层面的概念,线程是进程层面的概念。 就像同一个人在不同的管理体系中会有不同的身份一样,一个男人既可以是 孩子,爸爸,丈夫,或者程序员,视角不同功能也会不同。

如何证明是一个东西,继续再往下看。

执行task命令

看shell task 命令的执行结果:

task命令 查出每个任务在生命周期内的运行情况,它运行的内存空间,优先级,时间片,入口执行函数,进程ID,状态等等信息,非常的复杂。这么复杂的信息就需要一个结构体来承载。而这个结构体就是 LosTaskCB(任务控制块)

对应张大爷的故事:task就是一个用户的节目清单里的一个节目,用户总清单就是一个进程,所以上面会有很多的节目。

task长得什么样子

说LosTaskCB之前先说下官方文档任务状态对应的 define,可以看出task和线程是一个东西。

#define OS_TASK_STATUS_INIT         0x0001U
#define OS_TASK_STATUS_READY        0x0002U
#define OS_TASK_STATUS_RUNNING      0x0004U
#define OS_TASK_STATUS_SUSPEND      0x0008U
#define OS_TASK_STATUS_PEND         0x0010U
#define OS_TASK_STATUS_DELAY        0x0020U
#define OS_TASK_STATUS_TIMEOUT      0x0040U
#define OS_TASK_STATUS_PEND_TIME    0x0080U
#define OS_TASK_STATUS_EXIT         0x0100U

LosTaskCB长什么样?抱歉,它确实有点长,但还是要全部贴出全貌。

typedef struct {
   
   
    VOID            *stackPointer;      /**< Task stack pointer */ //非用户模式下的栈指针
    UINT16          taskStatus;         /**< Task status */   //各种状态标签,可以拥有多种标签,按位标识
    UINT16          priority;           /**< Task priority */  //任务优先级[0:31],默认是31级
    UINT16          policy;    //任务的调度方式(三种 .. LOS_SCHED_RR )
    UINT16          timeSlice;          /**< Remaining time slice *///剩余时间片
    UINT32          stackSize;          /**< Task stack size */  //非用户模式下栈大小
    UINTPTR         topOfStack;         /**< Task stack top */  //非用户模式下的栈顶 bottom = top + size
    UINT32          taskID;             /**< Task ID */    //任务ID,任务池本质是一个大数组,ID就是数组的索引,默认 < 128
    TSK_ENTRY_FUNC  taskEntry;          /**< Task entrance function */ //任务执行入口函数
    VOID            *joinRetval;        /**< pthread adaption */ //用来存储join线程的返回值
    VOID            *taskSem;           /**< Task-held semaphore */ //task在等哪个信号量
    VOID            *taskMux;           /**< Task-held mutex */  //task在等哪把锁
    VOID            *taskEvent;         /**< Task-held event */  //task在等哪个事件
    UINTPTR         args[4];            /**< Parameter, of which the maximum number is 4 */ //入口函数的参数 例如 main (int argc,char *argv[])
    CHAR            taskName[OS_TCB_NAME_LEN]; /**< Task name */ //任务的名称
    LOS_DL_LIST     pendList;           /**< Task pend node */  //如果任务阻塞时就通过它挂到各种阻塞情况的链表上,比如OsTaskWait时
    LOS_DL_LIST     threadList;         /**< thread list */   //挂到所属进程的线程链表上
    SortLinkList    sortList;           /**< Task sortlink node */ //挂到cpu core 的任务执行链表上
    UINT32          eventMask;          /**< Event mask */   //事件屏蔽
    UINT32          eventMode;          /**< Event mode */   //事件模式
    UINT32          priBitMap;          /**< BitMap for recording the change of task priority, //任务在执行过程中优先级会经常变化,这个变量用来记录所有曾经变化
                                             the priority can not be greater than 31 */   //过的优先级,例如 ..01001011 曾经有过 0,1,3,6 优先级
    INT32           errorNo;            /**< Error Num */
    UINT32          signal;             /**< Task signal */ //任务信号类型,(SIGNAL_NONE,SIGNAL_KILL,SIGNAL_SUSPEND,SIGNAL_AFFI)
    sig_cb          sig;    //信号控制块,这里用于进程间通讯的信号,类似于 linux singal模块
#if (LOSCFG_KERNEL_SMP == YES)
    UINT16          currCpu;            /**< CPU core number of this task is running on */ //正在运行此任务的CPU内核号
    UINT16          lastCpu;            /**< CPU core number of this task is running on last time */ //上次运行此任务的CPU内核号
    UINT16          cpuAffiMask;        /**< CPU affinity mask, support up to 16 cores */ //CPU亲和力掩码,最多支持16核,亲和力很重要,多核情况下尽量一个任务在一个CPU核上运行,提高效率
    UINT32          timerCpu;           /**< CPU core number of this task is delayed or pended */ //此任务的CPU内核号被延迟或挂起
#if (LOSCFG_KERNEL_SMP_TASK_SYNC == YES)
    UINT32          syncSignal;         /**< Synchronization for signal handling */ //用于CPU之间 同步信号
#endif
#if (LOSCFG_KERNEL_SMP_LOCKDEP == YES) //死锁检测开关
    LockDep         lockDep;
#endif
#if (LOSCFG_KERNEL_SCHED_STATISTICS == YES) //调度统计开关,显然打开这个开关性能会受到影响,鸿蒙默认是关闭的
    SchedStat       schedStat;          /**< Schedule statistics */ //调度统计
#endif
#endif
    UINTPTR         userArea;   //使用区域,由运行时划定,根据运行态不同而不同
    UINTPTR         userMapBase
鸿蒙内核分析】LiteOS-M内核源码分析任务任务调度——任务调度模块 调度,Schedule也称为Dispatch,是操作系统的一个重要模块,它负责选择系统要处理的下一个任务调度模块需要协调处于就绪状态的任务对资源的竞争,按优先级策略从就绪队列中获取高优先级的任务,给予资源使用权。本文我们来一起学习下调度模块的源代码,文中所涉及的源代码,所涉及的源码,以内核为例, 阅读详情

相关推荐

鸿蒙内核分析】LiteOS-M内核源码分析任务任务调度(1)任务

在文件中,定义的上下文的结构体如下,主要是浮点寄存器,通用寄存器。UINT32 S16;UINT32 S17;UINT32 S18;UINT32 S19;UINT32 S20;UINT32 S21;UINT32 S22;UINT32 S23;UINT32 S24;UINT32 S25;UINT32 S26;UINT32 S27;UINT32 S28;UINT32 S29;UINT32 S30;UINT32 S31;#endif。

2401_88547687的博客 2369

深入理解Linux内核进程的管理与调度(全知乎最详细)

在Linux2.4.18中(linux-2.5)之前的内核, 当很多任务都处于活动状态时, 调度器有很明显的限制. 这是由于调度器是使用一个复杂度为O(n)O(n)的算法实现的调度器采用基于优先级的设计,这个调度器和Linus在1992年发布的调度器没有大的区别。该调度器的pick next算法非常简单:对runqueue中所有进程的优先级进行依次进行比较,选择最高优先级的进程作为下一个被调度的进程。

嵌入式Linux内核的博客 1737

鸿蒙内核源码分析系列 | 读懂HarmonyOS内核源代码!

本系列从HarmonyOS架构层视角整理成文, 并用生活场景及讲故事的方式试图去解构内核,一窥究竟。帮助你读懂并快速理解鸿蒙操作系统源码。 1.鸿蒙内核源码分析(调度机制) 2.鸿蒙内核源码分析(进程管理) 3.鸿蒙内核源码分析(Task管理) 4.鸿蒙内核源码分析(内存管理) 5.鸿蒙内核源码分析(内存概念) 6.鸿蒙内核源码分析(内存映射) 7.鸿蒙内核源码分析(内存汇编) 8.鸿蒙内核源码分析(内存分配) 9.鸿蒙内核源码分析(必读)|用故事说内核 10.图解鸿蒙源码逐行注释分析(

HarmonyOS技术社区 1万+

linux内核分析(linux中的调度

在 Linux 中,调度器负责管理系统中的进程和线程的执行顺序,以确保 CPU 资源的有效利用。任务调度:决定哪个进程或线程在任何时刻获得 CPU 使用权。时间片分配:为每个任务分配执行时间,确保公平性和响应性。优先级处理:根据任务的优先级和其他调度策略,安排任务执行顺序。上下文切换:保存当前任务的状态,加载下一个任务的状态,以实现任务切换。调度器通过不同的调度策略(如完全公平调度器 CFS、实时调度策略等)来优化系统性能、响应时间和任务的公平性。实时任务优先级和。

m0_49476241的博客 2109

鸿蒙线程基础知识

https://developer.harmonyos.com/cn/docs/documentation/doc-guides/inter-thread-guidelines-0000000000038955 子线程如何返回到UI线程 https://developer.harmonyos.com/cn/docs/documentation/doc-guides/faq-ability-0000001125002304

舒小羽的博客 2426

linux 内核调度

linux 内核调度 文章目录一、Linux 内核常见的三种调度方法1.1 实时调度策略1.2 分时调度策略1.3 系统中既有分时调度又有时间片轮转调度和先进先出调度二、调度器的基础知识2.1 调度的概述2.2 调度器中的机制2.3 schedule() 函数2.4 pick_next_task 函数2.5 调度中的 nice 值2.6 获取和设置调度策略 一、Linux 内核常见的三种调度方法 SCHED_OTHER 分时调度策略 SCHED_FIFO 实时调度策略,先到先服务 SCHED_R

qq_29413633的博客 2193

Linux内核中的进程调度-进程调度基础

在深入探讨Linux内核的精妙世界中,进程调度无疑是最具挑战性也最为关键的一个环节。它作为操作系统核心功能的一部分,犹如交响乐团中的指挥家,精准而高效地协调着系统中各个进程的执行顺序和时间分配,确保整个系统的性能表现与资源利用达到最佳平衡。Linux内核的进程调度器不仅负责决定哪个进程将在CPU上运行,何时运行,还涉及到优先级管理、实时性保证、多处理器调度策略等诸多复杂问题。

qq_45652092的博客 1742

OpenHarmony 5.0】鸿蒙内核源码分析(任务调度) | 任务内核调度单元

前面已经说了任务内核调度层面的概念,调度算法保证了task有序的执行,调度机制详见其他姊妹的介绍。如此多的任务怎么管理和执行?管理靠任务池和就绪队列,执行靠调度算法。

adaedwa187545的博客 954

v04.03 鸿蒙内核源码分析(任务调度) | 内核调度单元是谁 |博客分析HarmonyOS源码

先看下鸿蒙task 命令的执行结果: 鸿蒙 task 的概念可理解为线程的概念,鸿蒙内核代码有 los_task.c 并没有los_thread.c 但官方文档里用了线程并未提及task相关的资料,但阅读鸿蒙内核源码就知道 los_task.c中各状态定义就是官方文档中的定义。 以下是官方的文档说明: 基本概念 从系统的角度看,线程是竞争系统资源的最小运行单元。线程可以使用或等待CPU、使用内存空间等系统资源,并独立于其它线程运行。 鸿蒙内核每个进程内的线程独立运行、独立调度,当前进...

日拱一卒,力出一孔 9206

v07.08 鸿蒙内核源码分析(调度机制) | 任务是如何被调度执行的 |博客分析HarmonyOS源码

提示:本文基于开源鸿蒙内核分析,官方源码【kernel_liteos_a】,官方文档【docs】 本文作者:鸿蒙内核发烧友,将持续研究鸿蒙内核,更新博文,敬请关注。内容仅代表个人观点,错误之处,欢迎大家指正完善。 本文分析任务调度机制源码 详见:../kernel/base/sched/sched_sq/los_sched.c 建议先阅读 阅读本文之前建议先读 鸿蒙内核源码分析(Task/线程管理) 鸿蒙内核源码分析(进程管理) 鸿蒙内核源码分析(调度队列) 以便对本文任务调度机制的理解

日拱一卒,力出一孔 3万+

v09.04 鸿蒙内核源码分析(调度故事) | 用故事说内核调度 |博客分析HarmonyOS源码

提示:本文基于开源鸿蒙内核分析,官方源码【kernel_liteos_a】官方文档【docs】参考文档【Huawei LiteOS】 本文作者:鸿蒙内核发烧友,应该是全国首创用故事的方式去说内核,让神秘的内核一丝不挂,栩栩如生,敬请关注。内容仅代表个人观点,错误之处,欢迎大家指正完善。本系列全部文章进入鸿蒙系统源码分析(总目录)查看 前言:因笔者在大学有痛苦阅读linux0.11内核的经历,所以一直有个心结,在很多同学眼中操作系统内核运作是神秘莫测的,一直想让更多人能明白其内在机制,甚至让一个没有学过计算

日拱一卒,力出一孔 3万+

鸿蒙内核源码分析调度机制

作者 | 深入研究鸿蒙鸿蒙内核发烧友出品 | CSDN(ID:CSDNnews)头图 | CSDN 下载自东方 IC阅读之前建议先读本系列其他文章,以便对本文任务调度机制的理解。为什么...

CSDN资讯 5434

v03.06 鸿蒙内核源码分析(时钟任务) | 调度的源动力从哪来 |博客分析HarmonyOS源码

时钟管理模块很简单,但却有内核最重要的代码断OsTickHandler()鸿蒙目前开放的是 轻量级的内核 lite os (LOS),所以tick的频率不会太高 详见代码: los_tick.c /** * @ingroup los_config * Number of Ticks in one second */ #ifndef LOSCFG_BASE_CORE_TICK_PER_SECOND #define LOSCFG_BASE_CORE_TICK_PER_SECOND 100 #e...

日拱一卒,力出一孔 6979
上一篇: 鸿蒙内核源码分析(时钟任务篇)
下一篇: 鸿蒙内核源码分析(任务管理篇) | 任务池是如何管理的?
OpenHarmony_小贾
博客等级 码龄3年 1万+粉丝 · 1181原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值