系统相关
首页 > 系统相关> > 鸿蒙内核源码分析(进程概念篇) | 进程都管理了哪些资源? | 百篇博客分析HarmonyOS源码 | v24.03

鸿蒙内核源码分析(进程概念篇) | 进程都管理了哪些资源? | 百篇博客分析HarmonyOS源码 | v24.03

作者:互联网

百万汉字注解 >> 精读内核源码,中文注解分析, 深挖地基工程,大脑永久记忆,四大码仓每日同步更新< gitee | github | csdn | coding >

百篇博客分析 >> 故事说内核,问答式导读,生活式比喻,表格化说明,图形化展示,主流站点定期更新中< oschina | csdn | 掘金 | harmony >


在这里插入图片描述

本篇说清楚进程

读本篇之前建议先读鸿蒙内核源码分析(总目录)调度故事篇,其中有对进程生活场景式的比喻.

官方基本概念

官方概念解读

官方文档最重要的一句话是进程是资源管理单元,注意是管理资源的, 资源是什么? 内存,任务,文件,信号量等等都是资源.故事篇中对进程做了一个形象的比喻(导演),负责节目(任务)的演出,负责协调节目运行时所需的各种资源.让节目能高效顺利的完成.

鸿蒙内核源码分析定位为深挖内核地基,构筑底层网图.就要解剖真身.进程(LosProcessCB)原始真身如下,本篇一一剖析它,看看它到底长啥样.

ProcessCB真身

typedef struct ProcessCB {
    CHAR                 processName[OS_PCB_NAME_LEN]; /**< Process name */ //进程名称
    UINT32               processID;                    /**< process ID = leader thread ID */ //进程ID,由进程池分配,范围[0,64]
    UINT16               processStatus;                /**< [15:4] process Status; [3:0] The number of threads currently
                                                            running in the process *///这里设计很巧妙.用一个16表示了两层逻辑 数量和状态,点赞!
    UINT16               priority;                     /**< process priority */ //进程优先级
    UINT16               policy;                       /**< process policy */ //进程的调度方式,默认抢占式
    UINT16               timeSlice;                    /**< Remaining time slice *///进程时间片,默认2个tick
    UINT16               consoleID;                    /**< The console id of task belongs  *///任务的控制台id归属
    UINT16               processMode;                  /**< Kernel Mode:0; User Mode:1; */ //模式指定为内核还是用户进程
    UINT32               parentProcessID;              /**< Parent process ID */ //父进程ID
    UINT32               exitCode;                     /**< process exit status */ //进程退出状态码
    LOS_DL_LIST          pendList;                     /**< Block list to which the process belongs */ //进程所属的阻塞列表,如果因拿锁失败,就由此节点挂到等锁链表上
    LOS_DL_LIST          childrenList;                 /**< my children process list */ //孩子进程都挂到这里,形成双循环链表
    LOS_DL_LIST          exitChildList;                /**< my exit children process list */ //那些要退出孩子进程挂到这里,白发人送黑发人。
    LOS_DL_LIST          siblingList;                  /**< linkage in my parent's children list */ //兄弟进程链表, 56个民族是一家,来自同一个父进程.
    ProcessGroup         *group;                       /**< Process group to which a process belongs */ //所属进程组
    LOS_DL_LIST          subordinateGroupList;         /**< linkage in my group list */ //进程是组长时,有哪些组员进程
    UINT32               threadGroupID;                /**< Which thread group , is the main thread ID of the process */ //哪个线程组是进程的主线程ID
    UINT32               threadScheduleMap;            /**< The scheduling bitmap table for the thread group of the
                                                            process */ //进程的各线程调度位图
    LOS_DL_LIST          threadSiblingList;            /**< List of threads under this process *///进程的线程(任务)列表
    LOS_DL_LIST          threadPriQueueList[OS_PRIORITY_QUEUE_NUM]; /**< The process's thread group schedules the
                                                                         priority hash table */ //进程的线程组调度优先级哈希表
    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 *///进程持有等待链表以支持wait/waitpid
#if (LOSCFG_KERNEL_SMP == YES)
    UINT32               timerCpu;     /**< CPU core number of this task is delayed or pended *///统计各线程被延期或阻塞的时间
#endif
    UINTPTR              sigHandler;   /**< signal handler */ //信号处理函数,处理如 SIGSYS 等信号 
    sigset_t             sigShare;     /**< signal share bit */ //信号共享位
#if (LOSCFG_KERNEL_LITEIPC == YES)
    ProcIpcInfo         ipcInfo;       /**< memory pool for lite ipc */ //用于进程间通讯的虚拟设备文件系统,设备装载点为 /dev/lite_ipc
#endif
    LosVmSpace          *vmSpace;       /**< VMM space for processes */ //虚拟空间,描述进程虚拟内存的数据结构,linux称为内存描述符
#ifdef LOSCFG_FS_VFS
    struct files_struct *files;        /**< Files held by the process */ //进程所持有的所有文件,注者称之为进程的文件管理器
#endif //每个进程都有属于自己的文件管理器,记录对文件的操作. 注意:一个文件可以被多个进程操作
    timer_t             timerID;       /**< iTimer */

#ifdef LOSCFG_SECURITY_CAPABILITY //安全能力
    User                *user;  //进程的拥有者
    UINT32              capability; //安全能力范围 对应 CAP_SETGID
#endif
#ifdef LOSCFG_SECURITY_VID
    TimerIdMap          timerIdMap;
#endif
#ifdef LOSCFG_DRIVERS_TZDRIVER
    struct file         *execFile;     /**< Exec bin of the process */
#endif
    mode_t umask;
} LosProcessCB;

结构体还是比较复杂,虽一一都做了注解,但还是不够清晰,没有模块化.这里把它分解成以下六大块逐一分析:

第一大块:和任务(线程)关系

    UINT32               threadGroupID;                /**< Which thread group , is the main thread ID of the process */ //哪个线程组是进程的主线程ID
    UINT32               threadScheduleMap;            /**< The scheduling bitmap table for the thread group of the
                                                            process */ //进程的各线程调度位图
    LOS_DL_LIST          threadSiblingList;            /**< List of threads under this process *///进程的线程(任务)列表
    LOS_DL_LIST          threadPriQueueList[OS_PRIORITY_QUEUE_NUM]; /**< The process's thread group schedules the
                                                                         priority hash table */ //进程的线程组调度优先级哈希表
    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 *///进程持有等待链表以支持wait/waitpid

进程和线程的关系是1:N的关系,进程可以有多个任务但一个任务不能同属于多个进程. 任务就是线程,是CPU的调度单元.线程的概念在鸿蒙内核源码分析(总目录)中的线程篇中有详细的介绍,可自行翻看. 任务是作为一种资源被进程管理的,进程为任务提供内存支持,提供文件支持,提供设备支持.

进程怎么管理线程的,进程怎么同步线程的状态?

第二大块:和其他进程的关系

    CHAR                 processName[OS_PCB_NAME_LEN]; /**< Process name */ //进程名称
    UINT32               processID;                    /**< process ID = leader thread ID */ //进程ID,由进程池分配,范围[0,64]
    UINT16               processStatus;                /**< [15:4] process Status; [3:0] The number of threads currently
                                                            running in the process *///这里设计很巧妙.用一个16表示了两层逻辑 数量和状态,点赞!
    UINT16               priority;                     /**< process priority */ //进程优先级
    UINT16               policy;                       /**< process policy */ //进程的调度方式,默认抢占式
    UINT16               timeSlice;                    /**< Remaining time slice *///进程时间片,默认2个tick
    UINT16               consoleID;                    /**< The console id of task belongs  *///任务的控制台id归属
    UINT16               processMode;                  /**< Kernel Mode:0; User Mode:1; */ //模式指定为内核还是用户进程
    UINT32               parentProcessID;              /**< Parent process ID */ //父进程ID
    UINT32               exitCode;                     /**< process exit status */ //进程退出状态码
    LOS_DL_LIST          pendList;                     /**< Block list to which the process belongs */ //进程所属的阻塞列表,如果因拿锁失败,就由此节点挂到等锁链表上
    LOS_DL_LIST          childrenList;                 /**< my children process list */ //孩子进程都挂到这里,形成双循环链表
    LOS_DL_LIST          exitChildList;                /**< my exit children process list */ //那些要退出孩子进程挂到这里,白发人送黑发人。
    LOS_DL_LIST          siblingList;                  /**< linkage in my parent's children list */ //兄弟进程链表, 56个民族是一家,来自同一个父进程.
    #if (LOSCFG_KERNEL_LITEIPC == YES)
    ProcIpcInfo         ipcInfo;       /**< memory pool for lite ipc */ //用于进程间通讯的虚拟设备文件系统,设备装载点为 /dev/lite_ipc
    #endif

进程是家族式管理的,内核态进程和用户态进程分别有自己的根祖先,祖先进程在内核初始化时就创建好了,分别是1号(用户进程祖先)和2号(内核进程祖先)进程.进程刚生下来就确定了自己的基因,基因决定了你的权限不同, 父亲是谁,兄弟姐妹都有谁都已经安排好了,跟人一样,没法选择出生. 但进程可以有自己的子子孙孙, 从你这一脉繁衍下来的,这很像人类的传承方式.最终会形成树状结构,每个进程都能找到自己的位置.进程的管理遵循以下几点原则:

第三大块:进程的五种状态

第四大块:和内存的关系

    LosVmSpace          *vmSpace;       /**< VMM space for processes */ //虚拟空间,描述进程虚拟内存的数据结构,linux称为内存描述符

第五大块:和文件的关系

#ifdef LOSCFG_FS_VFS
    struct files_struct *files;        /**< Files held by the process */ //进程所持有的所有文件,注者称之为进程的文件管理器
#endif //每个进程都有属于自己的文件管理器,记录对文件的操作. 注意:一个文件可以被多个进程操作

进程与文件系统有关的就只有files_struct,可理解为进程的文件管理器,文件也是很复杂的一大块, 后续有系列篇来讲解文件系统的实现. 理解文件系统的主脉络是:

第六大块:辅助工具

#if (LOSCFG_KERNEL_SMP == YES)
    UINT32               timerCpu;     /**< CPU core number of this task is delayed or pended *///统计各线程被延期或阻塞的时间
#endif
#ifdef LOSCFG_SECURITY_CAPABILITY //安全能力
    User                *user;  //进程的拥有者
    UINT32              capability; //安全能力范围 对应 CAP_SETGID
#endif
#ifdef LOSCFG_SECURITY_VID
    TimerIdMap          timerIdMap;
#endif
#ifdef LOSCFG_DRIVERS_TZDRIVER
    struct file         *execFile;     /**< Exec bin of the process */
#endif

其余是一些安全性,统计性的能力.

以上就是进程的全貌,看清楚它鸿蒙内核的影像会清晰很多!

鸿蒙源码百篇博客 往期回顾

参与贡献

喜欢请大方 点赞+关注+收藏 吧

标签:源码,csdn,harmony,v24.03,进程,线程,掘金,内核
来源: https://blog.51cto.com/u_14940441/2729223