1# 进程 2 3 4## 基本概念 5 6进程是系统资源管理的最小单元。OpenHarmony LiteOS-A 内核提供的进程模块主要用于实现用户态进程的隔离,内核态被视为一个进程空间,不存在其它进程(KIdle除外,KIdle进程是系统提供的空闲进程,和KProcess共享一个进程空间。KProcess 是内核态进程的根进程,KIdle 是其子进程)。 7 8- 进程模块主要为用户提供多个进程,实现了进程之间的切换和通信,帮助用户管理业务程序流程。 9 10- 进程采用抢占式调度机制,采用高优先级优先+同优先级时间片轮转的调度算法。 11 12- 进程一共有32个优先级(0-31),用户进程可配置的优先级有22个(10-31),最高优先级为10,最低优先级为31。 13 14- 高优先级的进程可抢占低优先级进程,低优先级进程必须在高优先级进程阻塞或结束后才能得到调度。 15 16- 每一个用户态进程均拥有自己独立的进程空间,相互之间不可见,实现进程间隔离。 17 18- 用户态根进程init由内核态创建,其它用户态子进程均由init进程fork而来。 19 20**进程状态说明:** 21 22- 初始化(Init):进程正在被创建。 23 24- 就绪(Ready):进程在就绪列表中,等待CPU调度。 25 26- 运行(Running):进程正在运行。 27 28- 阻塞(Pending):进程被阻塞挂起。本进程内所有的线程均被阻塞时,进程被阻塞挂起。 29 30- 僵尸(Zombies):进程运行结束,等待父进程回收其控制块资源。 31 32 **图1** 进程状态迁移示意图 33 34 ![zh-cn_image_0000001219007317](figures/zh-cn_image_0000001219007317.png) 35 36**进程状态迁移说明:** 37 38- Init→Ready: 39 进程创建或 fork 时,拿到对应进程控制块后进入 Init 状态,即进程初始化阶段,当该阶段完成后进程将被插入调度队列,此时进程进入就绪状态。 40 41- Ready→Running: 42 进程创建后进入就绪态,发生进程切换时,就绪列表中优先级最高且获得时间片的进程被执行,从而进入运行态。若此时该进程中已无其它线程处于就绪态,则进程从就绪列表删除,只处于运行态;若此时该进程中还有其它线程处于就绪态,则该进程依旧在就绪队列,此时进程的就绪态和运行态共存,但对外呈现的进程状态为运行态。 43 44- Running→Pending: 45 进程在最后一个线程转为阻塞态时, 进程内所有的线程均处于阻塞态,此时进程同步进入阻塞态,然后发生进程切换。 46 47- Pending→Ready: 48 阻塞进程内的任意线程恢复就绪态时,进程被加入到就绪队列,同步转为就绪态。 49 50- Ready→Pending: 51 进程内的最后一个就绪态线程转为阻塞态时,进程从就绪列表中删除,进程由就绪态转为阻塞态。 52 53- Running→Ready: 54 进程由运行态转为就绪态的情况有以下两种: 55 56 1. 有更高优先级的进程创建或者恢复后,会发生进程调度,此刻就绪列表中最高优先级进程变为运行态,那么原先运行的进程由运行态变为就绪态。 57 2. 若进程的调度策略为 LOS_SCHED_RR(时间片轮转),且存在同一优先级的另一个进程处于就绪态,则该进程的时间片消耗光之后,该进程由运行态转为就绪态,另一个同优先级的进程由就绪态转为运行态。 58 59- Running→Zombies: 60 当进程的主线程或所有线程运行结束后,进程由运行态转为僵尸态,等待父进程回收资源。 61 62 63## 运行机制 64 65OpenHarmony 提供的进程模块主要用于实现用户态进程的隔离,支持用户态进程的创建、退出、资源回收、设置/获取调度参数、获取进程ID、设置/获取进程组ID等功能。 66 67用户态进程通过fork父进程而来,fork进程时会将父进程的进程虚拟内存空间clone到子进程,子进程实际运行时通过写时复制机制将父进程的内容按需复制到子进程的虚拟内存空间。 68 69进程只是资源管理单元,实际运行是由进程内的各个线程完成的,不同进程内的线程相互切换时会进行进程空间的切换。 70 71 **图2** 进程管理示意图 72 73 ![zh-cn_image_0000001199736949](figures/zh-cn_image_0000001199736949.png) 74 75 76## 开发指导 77 78 79### 接口说明 80 81##### 表1 进程及进程组 82 83| 接口名 | 接口描述 | 84| ------------------------- | ---------------------- | 85| LOS_GetCurrProcessID | 获取当前进程的进程ID | 86| LOS_GetProcessGroupID | 获取指定进程的进程组ID | 87| LOS_GetCurrProcessGroupID | 获取当前进程的进程组ID | 88 89##### 表2 用户及用户组 90 91| 接口名 | 接口描述 | 92| ----------------- | ---------------------------------------- | 93| LOS_GetUserID | 获取当前进程的用户ID | 94| LOS_GetGroupID | 获取当前进程的用户组ID | 95| LOS_CheckInGroups | 检查指定用户组ID是否在当前进程的用户组内 | 96 97##### 表3 进程调度控制 98 99| 接口名 | 接口 | 100| ----------------------- | -------------------------------------------- | 101| LOS_GetProcessScheduler | 获取指定进程的调度策略 | 102| LOS_SetProcessScheduler | 设置指定进程的调度参数,包括优先级和调度策略 | 103| LOS_SetProcessPriority | 设置进程优先级 | 104| LOS_GetProcessPriority | 获取进程优先级 | 105 106##### 表4 系统进程信息获取 107 108| 接口名 | 接口描述 | 109| --------------------------- | -------------------------- | 110| LOS_GetSystemProcessMaximum | 获取系统支持的最大进程数目 | 111| LOS_GetUsedPIDList | 获得已使用的进程ID列表 | 112 113##### 表5 进程创建与结束 114 115| 接口名 | 接口描述 | 116| ---------- | -------------------------- | 117| LOS_Fork | 创建子进程 | 118| LOS_Wait | 等待子进程结束并回收子进程 | 119| LOS_Waitid | 等待相应ID的进程结束 | 120| LOS_Exit | 退出进程 | 121 122 123 124### 开发流程 125 126不支持内核态进程创建,内核态不涉及进程相关开发。 127 128> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** 129> - idle线程的数量跟随CPU核心数,每个CPU均有一个相应的idle线程。 130> 131> - 不支持创建除KProcess和KIdle进程之外的其它内核态进程。 132> 133> - 用户态进程通过系统调用进入内核态后创建的线程属于KProcess, 不属于当前用户态进程。 134