鸿蒙轻内核A核源码分析系列七 进程管理 (1)

本文开始继续分析OpenHarmony LiteOS-A内核的源代码,接下来会分析进程和任务管理模块。本文中所涉及的源码,以OpenHarmony LiteOS-A内核为例,均可以在开源站点 https://gitee.com/openharmony/kernel_liteos_a 获取。如果涉及开发板,则默认以hispark_taurus为例。

本文先熟悉下进程管理的概念、运行机制和编程接口。

1、LiteOS-A内核进程基本概念

进程是系统资源管理的最小单元。OpenHarmony LiteOS-A内核提供的进程模块主要用于实现用户态进程的隔离,内核态被视为一个进程空间,不存在其它进程(KIdle除外,KIdle进程是系统提供的空闲进程,和KProcess共享一个进程空间)。

1.1 LiteOS-A内核进程特征

LiteOS-A内核进程有如下特征:

  • 进程模块主要为用户提供多个进程,实现了进程之间的切换和通信,帮助用户管理业务程序流程。

  • 进程采用抢占式调度机制,采用高优先级优先+同优先级时间片轮转的调度算法。

  • 进程一共有32个优先级(0-31),用户进程可配置的优先级有22个(10-31),最高优先级为10,最低优先级为31。

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

  • 每一个用户态进程均拥有自己独立的进程空间,相互之间不可见,实现进程间隔离。

  • 用户态根进程init由内核态创建,其它用户态子进程均由init进程fork而来。

1.2 LiteOS-A内核进程状态

LiteOS-A内核进程状态包含初始化态、就绪态、运行态、阻塞态、僵死态等几种状态。

  • 初始化(Init):进程正在被创建。

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

  • 运行(Running):进程正在运行。

阻塞(Pending):进程被阻塞挂起。本进程内所有的线程均被阻塞时,进程被阻塞挂起。

  • 僵尸(Zombies):进程运行结束,等待父进程回收其控制块资源。

各个状态迁移示意图如下所示,图片来自openharmony docs文档仓:

进程状态迁移说明如下:

  • 1、Init→Ready: 进程创建或fork时,拿到该进程控制块后进入Init状态,处于进程初始化阶段,当进程初始化完成将进程插入调度队列,此时进程进入就绪状态。

  • 2、Ready→Running: 进程创建后进入就绪态,发生进程切换时,就绪列表中最高优先级的进程被执行,从而进入运行态。若此时该进程中已无其它线程处于就绪态,则进程从就绪列表删除,只处于运行态;若此时该进程中还有其它线程处于就绪态,则该进程依旧在就绪队列,此时进程的就绪态和运行态共存,但对外呈现的进程状态为运行态。

  • 3、Running→Pending: 进程在最后一个线程转为阻塞态时, 进程内所有的线程均处于阻塞态,此时进程同步进入阻塞态,然后发生进程切换。

  • 4、Pending→Ready: 阻塞进程内的任意线程恢复就绪态时,进程被加入到就绪队列,同步转为就绪态。

  • 5、Ready→Pending: 进程内的最后一个就绪态线程转为阻塞态时,进程从就绪列表中删除,进程由就绪态转为阻塞态。

  • 6、Running→Ready: 进程由运行态转为就绪态的情况有以下两种:

    • 6.1 有更高优先级的进程创建或者恢复后,会发生进程调度,此刻就绪列表中最高优先级进程变为运行态,那么原先运行的进程由运行态变为就绪态。
    • 6.2 若进程的调度策略为LOS_SCHED_RR,且存在同一优先级的另一个进程处于就绪态,则该进程的时间片消耗光之后,该进程由运行态转为就绪态,另一个同优先级的进程由就绪态转为运行态。
  • 7、Running→Zombies: 当进程的主线程或所有线程运行结束后,进程由运行态转为僵尸态,等待父进程回收资源。

2、LiteOS-A内核进程运行机制

OpenHarmony 提供的进程模块主要用于实现用户态进程的隔离,支持用户态进程的创建、退出、资源回收、设置/获取调度参数、获取进程ID、设置/获取进程组ID等功能。用户态进程通过fork父进程而来,fork进程时会将父进程的进程虚拟内存空间clone到子进程,子进程实际运行时通过写时复制机制将父进程的内容按需复制到子进程的虚拟内存空间。进程只是资源管理单元,实际运行是由进程内的各个线程完成的,不同进程内的线程相互切换时会进行进程空间的切换。

3、LiteOS-A内核进程模块接口

3.1 LiteOS-A内核进程模块对外接口

进程模块对外接口文件kernel\include\los_process.h定义的接口,如下表所示。

功能分类接口名称描述
进程调度参数控制LOS_GetProcessScheduler获取指定进程的调度策略
LOS_SetProcessScheduler设置指定进程的调度参数,包括优先级和调度策略
LOS_GetProcessPriority获取指定进程的优先级
LOS_SetProcessPriority设置指定进程的优先级
进程操作LOS_Wait等待子进程结束并回收子进程
LOS_Waitid等待子进程结束并回收子进程
LOS_Exit退出进程
LOS_ForkFork进程
进程组LOS_GetProcessGroupID获取指定进程的进程组ID
LOS_GetCurrProcessGroupID获取当前进程的进程组ID
获取进程IDLOS_GetCurrProcessID获取当前进程的进程ID
LOS_GetUsedPIDList获取已用的进程ID列表,输出到进程ID数组
用户及用户组LOS_GetUserID获取当前进程的用户ID
LOS_GetGroupID获取当前进程的用户组ID
LOS_CheckInGroups检查指定用户组ID是否在当前进程的用户组内
系统支持的最大进程数LOS_GetSystemProcessMaximum获取系统支持的最大进程数目
文件描述符表LOS_GetFdTable根据进程ID获取文件描述符表

完整的接口声明如下:

extern INT32 LOS_Fork(UINT32 flags, const CHAR *name, const TSK_ENTRY_FUNC entry, UINT32 stackSize);extern INT32 LOS_SetProcessPriority(INT32 pid, UINT16 prio);extern INT32 LOS_GetProcessPriority(INT32 pid);extern INT32 LOS_GetProcessScheduler(INT32 pid);extern INT32 LOS_SetProcessScheduler(INT32 pid, UINT16 policy, UINT16 prio);extern UINT32 LOS_GetCurrProcessID(VOID);extern INT32 LOS_Wait(INT32 pid, USER INT32 *status, UINT32 options, VOID *rusage);extern INT32 LOS_Waitid(INT32 pid, USER siginfo_t *info, UINT32 options, VOID *rusage);extern INT32 LOS_GetCurrProcessGroupID(VOID);extern INT32 LOS_GetProcessGroupID(UINT32 pid);extern VOID LOS_Exit(INT32 status);extern UINT32 LOS_GetSystemProcessMaximum(VOID);#ifdef LOSCFG_SECURITY_CAPABILITY
extern BOOL LOS_CheckInGroups(UINT32 gid);
#endif
extern INT32 LOS_GetUserID(VOID);
extern INT32 LOS_GetGroupID(VOID);extern INT32 LOS_GetUsedPIDList(UINT32 *pidList, INT32 pidMaxNum);#ifdef LOSCFG_FS_VFS
struct fd_table_s *LOS_GetFdTable(UINT32 pid);
#endif

3.2 LiteOS-A内核进程模块结构体

私有头文件kernel\base\include\los_process_pri.h中定义了宏、结构体等。进程组、进程控制块结构体如下。对于进程组,如⑴所示,进程组的编号等于创建该进程组的进程的进程编号。每个进程组维护一个链表挂载本组的非僵尸态进程,还维护一个链表挂载本组的僵尸态进程。所有的进程都通过链表节点groupList挂载到全局进程组链表上,可以方便管理进程组。

进程控制块结构体比较复杂,⑵-⑶维护进程的名称、ID编号、状态、模式、退出状态等等,⑷-⑸维护各种链表,进程组信息,线程数量等。接下来,维护多核时的CPU信息,信号信息,虚拟地址框架,文件,安全能力等。涉及具体代码时,再深入分析这些结构体成员。

    typedef struct {
⑴      UINT32      groupID;         /**< Process group ID is the PID of the process that created the group */LOS_DL_LIST processList;     /**< List of processes under this process group */LOS_DL_LIST exitProcessList; /**< List of closed processes (zombie processes) under this group */LOS_DL_LIST groupList;       /**< Process group list */} ProcessGroup;typedef struct ProcessCB {
⑵      CHAR                 processName[OS_PCB_NAME_LEN]; /**< Process name */UINT32               processID;                    /**< Process ID */UINT16               processStatus;                /**< [15:4] Process Status; [3:0] The number of threads currentlyrunning in the process */UINT16               consoleID;                    /**< The console id of task belongs  */UINT16               processMode;                  /**< Kernel Mode:0; User Mode:1; */UINT32               parentProcessID;              /**< Parent process ID */
⑶      UINT32               exitCode;                     /**< Process exit status */
⑷      LOS_DL_LIST          pendList;                     /**< Block list to which the process belongs */LOS_DL_LIST          childrenList;                 /**< Children process list */LOS_DL_LIST          exitChildList;                /**< Exit children process list */LOS_DL_LIST          siblingList;                  /**< Linkage in parent's children list */ProcessGroup         *group;                       /**< Process group to which a process belongs */LOS_DL_LIST          subordinateGroupList;         /**< Linkage in group list */UINT32               threadGroupID;                /**< Which thread group , is the main thread ID of the process */LOS_DL_LIST          threadSiblingList;            /**< List of threads under this process */volatile UINT32      threadNumber; /**< Number of threads alive under this process */UINT32               threadCount;  /**< Total number of threads created under this process */
⑸      LOS_DL_LIST          waitList;     /**< The process holds the waitLits to support wait/waitpid */#ifdef LOSCFG_KERNEL_SMPUINT32               timerCpu;     /**< CPU core number of this task is delayed or pended */#endifUINTPTR              sigHandler;   /**< Signal handler */sigset_t             sigShare;     /**< Signal share bit */#ifdef LOSCFG_KERNEL_LITEIPCProcIpcInfo          *ipcInfo;      /**< Memory pool for lite ipc */#endif#ifdef LOSCFG_KERNEL_VMLosVmSpace           *vmSpace;     /**< VMM space for processes */#endif#ifdef LOSCFG_FS_VFSstruct files_struct  *files;       /**< Files held by the process */#endiftimer_t              timerID;      /**< ITimer */#ifdef LOSCFG_SECURITY_CAPABILITYUser                *user;UINT32              capability;#endif#ifdef LOSCFG_SECURITY_VIDTimerIdMap           timerIdMap;#endif#ifdef LOSCFG_DRIVERS_TZDRIVERstruct Vnode        *execVnode;   /**< Exec bin of the process */#endifmode_t               umask;#ifdef LOSCFG_KERNEL_CPUPOsCpupBase           *processCpup; /**< Process cpu usage */#endifstruct rlimit        *resourceLimit;} LosProcessCB;

3.3 LiteOS-A内核进程模块内联函数

私有头文件kernel\base\include\los_process_pri.h中还定义了内联函数等。下述几个函数用于判断进程是否未使用,是否未激活状态,是否死亡进程,是否初始化,是否用户态进程等。

STATIC INLINE BOOL OsProcessIsUnused(const LosProcessCB *processCB)
{return ((processCB->processStatus & OS_PROCESS_FLAG_UNUSED) != 0);
}STATIC INLINE BOOL OsProcessIsInactive(const LosProcessCB *processCB)
{return ((processCB->processStatus & (OS_PROCESS_FLAG_UNUSED | OS_PROCESS_STATUS_INACTIVE)) != 0);
}STATIC INLINE BOOL OsProcessIsDead(const LosProcessCB *processCB)
{return ((processCB->processStatus & (OS_PROCESS_FLAG_UNUSED | OS_PROCESS_STATUS_ZOMBIES)) != 0);
}STATIC INLINE BOOL OsProcessIsInit(const LosProcessCB *processCB)
{return (processCB->processStatus & OS_PROCESS_STATUS_INIT);
}
STATIC INLINE BOOL OsProcessIsUserMode(const LosProcessCB *processCB)
{return (processCB->processMode == OS_USER_MODE);
}

下述几个函数对指定进程设置不同的退出代码,coredump、signal等等。

/** Process exit code* 31    15           8           7        0* |     | exit code  | core dump | signal |*/
#define OS_PRO_EXIT_OK 0
STATIC INLINE VOID OsProcessExitCodeCoreDumpSet(LosProcessCB *processCB)
{processCB->exitCode |= 0x80U;
}STATIC INLINE VOID OsProcessExitCodeSignalSet(LosProcessCB *processCB, UINT32 signal)
{processCB->exitCode |= signal & 0x7FU;
}STATIC INLINE VOID OsProcessExitCodeSignalClear(LosProcessCB *processCB)
{processCB->exitCode &= (~0x7FU);
}STATIC INLINE BOOL OsProcessExitCodeSignalIsSet(LosProcessCB *processCB)
{return (processCB->exitCode) & 0x7FU;
}STATIC INLINE VOID OsProcessExitCodeSet(LosProcessCB *processCB, UINT32 code)
{processCB->exitCode |= ((code & 0x000000FFU) << 8U) & 0x0000FF00U; /* 8: Move 8 bits to the left, exitCode */
}

小结

本文介绍了进程管理的概念、运行机制和编程接口。

如果大家想更加深入的学习 OpenHarmony 开发的内容,不妨可以参考以下相关学习文档进行学习,助你快速提升自己:

OpenHarmony 开发环境搭建:https://qr18.cn/CgxrRy

《OpenHarmony源码解析》:https://qr18.cn/CgxrRy

  • 搭建开发环境
  • Windows 开发环境的搭建
  • Ubuntu 开发环境搭建
  • Linux 与 Windows 之间的文件共享
  • ……

系统架构分析:https://qr18.cn/CgxrRy

  • 构建子系统
  • 启动流程
  • 子系统
  • 分布式任务调度子系统
  • 分布式通信子系统
  • 驱动子系统
  • ……

OpenHarmony 设备开发学习手册:https://qr18.cn/CgxrRy

在这里插入图片描述

OpenHarmony面试题(内含参考答案):https://qr18.cn/CgxrRy

写在最后

  • 如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:
  • 点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。
  • 关注小编,同时可以期待后续文章ing🚀,不定期分享原创知识。
  • 想要获取更多完整鸿蒙最新学习资源,请移步前往小编:https://qr21.cn/FV7h05

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/852220.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

spring中IOC容器创建流程

跳转参考地址&#xff1a;https://wuliqun.cn/details?pps53

【安装笔记-20240613-Linux-在 OpenWrt 的 LuCI界面支持命令行调试】

安装笔记-系列文章目录 安装笔记-20240613-Linux-在 OpenWrt 的 LuCI界面支持命令行调试 文章目录 安装笔记-系列文章目录安装笔记-20240613-Linux-在 OpenWrt 的 LuCI界面支持命令行调试 前言一、软件介绍名称&#xff1a;ttyd主页官方介绍特点 二、安装步骤测试版本&#xf…

两种典型的嵌入式系统架构模式

大多数嵌入式系统都具备实时特征&#xff0c;那么&#xff0c;这种嵌入式系统的典型架构可概括为两种模式&#xff0c;即层次化模式架构和递归模式架构。 1.层次化模式架构 为了达到概念一致性&#xff0c;许多系统通过层次化的方法进行搭建。这样做的结果是&#xff1a;位于高…

Chisel入门——在windows系统下部署Chisel环境并点亮FPGA小灯等实验

Chisel入门——在windows系统下部署Chisel环境并点亮FPGA小灯等实验 一、chisel简介二、vscode搭建scala开发环境2.1 安装Scala官方插件2.2 java版本&#xff08;本人用的是jdk18&#xff09;2.3 下载Scala Windows版本的二进制文件2.4 配置环境变量2.5 scala测试2.6 vscode运行…

axure制作菜单下拉、隐藏、点击选中效果

在高保真原型中&#xff0c;制作导航栏菜单时&#xff0c;需要达到点击下拉按钮&#xff0c;子菜单自动弹出&#xff0c;点击其中一个子菜单项可栏目变为选中状态且跳转到对应的子页面。制作材料可以从antdesign中去下载&#xff0c;以下述网络配置菜单为例。在箭头处添加互动效…

RedHat8.4离线升级内核(漏洞编号CVE-2024-1086)

一、背景 针对Linux内核提取权限漏洞 (漏洞编号CVE-2024-1086&#xff09;&#xff0c;整理离线环境的修复方案。本文以离线修复方案为主进行说明&#xff0c;第八章对在线修复方案进行说明。 (一) 漏洞简介 近日&#xff0c;绿盟科技CERT监测网上有研究员公开披露了一个Lin…

SpringBoot Vue Bootstrap 旅游管理系统

SpringBoot Vue 旅游管理系统源码&#xff0c;附带环境安装&#xff0c;运行说明 源码地址 开发环境 jdk1.8,mysql8,nodejs16,navicat,idea 使用技术springboot mybatis vue bootstrap 部分功能截图预览

【SQLAlChemy】常见的数据类型有哪些,Column可选的参数有哪些呢?

常见数据类型与Column参数 常见类型 Integer&#xff1a;整数类型&#xff0c;对应数据库的 int 类型。Float&#xff1a;浮点数类型&#xff0c;对应数据库的 float 类型。它占用 32 位空间。Double&#xff1a;双精度浮点数类型&#xff0c;对应数据库的 double 类型&#…

【CS.PL】Lua 编程之道: 基础语法和数据类型 - 进度16%

2 初级阶段 —— 基础语法和数据类型 文章目录 2 初级阶段 —— 基础语法和数据类型2.0 关键字(keywords) &#x1f525;2.1 注释与标识符2.1.1 注释2.1.2 标识符 2.2 变量与赋值2.2.1 所有变量默认是全局变量 ≠ local, 有一个例外2.2.2 local变量是局部变量, 以end作为边界2.…

创建节约机关怎样向媒体投稿报道宣传?

创建节约机关并向媒体投稿报道宣传是一项重要的工作&#xff0c;它不仅能够提升机关的形象&#xff0c;还能促进社会各界对节约型社会的认识和支持。 作为一名新晋信息宣传员,初入职场的我满腔热血,怀揣着用文字传递价值的理想,却在投稿的道路上屡遭波折。面对每月的宣传任务,我…

表 达式树

》》》可以借助 LINQPad工具 using System; using System.Collections.Generic; using System.Data.Entity; using System.Linq; using System.Linq.Expressions; using System.Text; using System.Threading.Tasks; using System.Transactions;namespace EFDemo {public cla…

vite工程化搭建vue项目之自动按需导入

背景 当我们在使用vue3组合式开发的时候&#xff0c;大多数情况下我们的代码可能是这样的 <script setup lang"ts"> import { ref, reactive, toRefs, onMounted, computed } from vue; defineProps({}); </script><template><div></di…

共模信号与差模信号

差模信号又称串模信号&#xff0c;指的是两根线之间的信号差值&#xff1b;而共模信号又称对地信号&#xff0c;指的是两根线分别对地的信号。 差模信号&#xff1a;大小相等&#xff0c;方向相反的信号。共模信号&#xff1a;大小相等&#xff0c;方向相同的信号。 对于两输…

python的np.array()函数

1、创建数组 2、 与矩阵相关的函数 3、与排序相关的函数 4、 一元计算函数 5、 多元计算函数 6、 与文件读写相关的函数 7、与数组形状、属性相关的函数 8、 常用计算函数 9、 数组选取:切片和索引 10、np.random相关函数 Numpy常用的20个函数 一…

京准电钟 | 对比GPS,北斗卫星授时的场景有哪些?

京准电钟 | 对比GPS&#xff0c;北斗卫星授时的场景有哪些&#xff1f; 京准电钟 | 对比GPS&#xff0c;北斗卫星授时的场景有哪些&#xff1f; 对比国外的GPS&#xff0c;我国北斗卫星授时由于其高精度和稳定性&#xff0c;在各个领域都有广泛的应用场景。 以下是一些单北斗卫…

为什么需要负样本

假如我们只有正样本&#xff0c;模型在最开始训练的时候都是错误的&#xff0c;随着模型的迭代&#xff0c;准确率逐渐从0到1&#xff0c;最终将所有的样本都判别成正样本&#xff0c;也就是都在线的上方。 但真实的场景中有正有负&#xff0c;例如我们要做一个猫狗分类器&…

WINUI——CommunityToolkit.Mvvm Messenger接收消息时报错:Cannot access a disposed object.

背景 WINUI开发时使用CommunityToolkit.Mvvm的Messemger让UI展示一些信息时出现错误&#xff1a; System.ObjectDisposedException:“Cannot access a disposed object. ObjectDisposed_ObjectName_Name” 详细见下述截图&#xff1a; 开发环境 WIN11 WINUI&#xff13; …

如何在3天内开发一个鸿蒙app

华为鸿蒙操作系统&#xff08;HarmonyOS&#xff09;自2.0版本正式上线以来&#xff0c;在短时间内就部署超过了2亿台设备&#xff0c;纵观全球操作系统的发展史&#xff0c;也是十分罕见的。与其他手机操作系统不同&#xff0c;HarmonyOS自诞生之日起&#xff0c;就是一款面向…

【C++取经之路】继承

目录 继承的概念及定义 单继承的格式 继承方式和访问限定符 继承后子类访问基类成员的权限 基类和派生类对象赋值转换 切片 继承中的作用域 引申&#xff1a;重载和隐藏的区别 派生类的默认成员函数 继承与友元 继承与静态成员 如何实现一个不能被继承的类 复杂的…

【Java】解决Java报错:IllegalStateException during HTTP Request

文章目录 引言一、IllegalStateException的定义与概述1. 什么是IllegalStateException&#xff1f;2. IllegalStateException在HTTP请求中的常见触发场景3. 示例代码 二、解决方案1. 确保响应只被提交一次2. 正确管理Servlet的生命周期3. 避免重复访问输入流和输出流4. 使用框架…