往期知识点记录:
- 鸿蒙(HarmonyOS)应用层开发(北向)知识点汇总
- OpenHarmony轻量系统服务管理-samgr主要接口思维导图(1)
- OpenHarmony轻量系统服务管理-samgr主要接口思维导图(2)
- OpenHarmony轻量系统服务管理-samgr:common赏析及实现
- OpenHarmony轻量系统服务管理-samgr:iunknown赏析
- OpenHarmony轻量系统服务管理-samgr:iunknown实现分析
- OpenHarmony轻量系统服务管理samgr-message赏析
- OpenHarmony轻量系统服务管理samgr-message实现分析(1)
- OpenHarmony轻量系统服务管理samgr-message实现分析(2)
- OpenHarmony轻量系统服务管理samgr-service赏析
- OpenHarmony轻量系统服务管理samgr-samgr_lite赏析
- OpenHarmony轻量系统服务管理samgr-feature赏析及实现
- OpenHarmony轻量系统服务管理samgr-service实现分析(1)
- OpenHarmony轻量系统服务管理samgr-service实现分析(2)
- OpenHarmony轻量系统服务管理samgr-task_manager赏析及实现(1)
- 持续更新中……
一、前言
在task_manager部分,主要负责对任务的管理,从消息队列获取消息并处理。在distributedschedule_samgr_lite\samgr\source\task_manager.h中对声明对任务池操作的方法。在distributedschedule_samgr_lite\samgr\source\task_manager.c中对相关方法进行了实现。
二、头文件分析
#ifndef MAX_TASK_SIZE
#define MAX_TASK_SIZE 0xFFFFFF //任务的最大数
#endif
//引用的最大数
#define MAX_REF_NUM 15
//消息处理的最大时间间隔
#define MSG_PROC_THRESHOLD (10 * 1000)
#define GET_REMAIN_TIME(time) ((0xFFFFFFFF - (time)) + 1)
//计算时间间隔
#define GET_INTERVAL(last, now) (((last) > (now)) ? (GET_REMAIN_TIME(last) + (now)) : ((now) - (last)))
typedef struct TaskPool TaskPool;
struct TaskPool {
MQueueId queueId; //消息队列ID
uint16 stackSize; //栈大小,用于配置线程的栈
uint8 priority; //任务的优先级,用于配置线程的优先级
uint8 size; //任务池的大小,维护的线程数
uint8 top; //标识tasks中的线程ID的个数
int8 ref; //引用数
ThreadId tasks[0]; //记录任务池下属的线程ID
};
//创建任务池
TaskPool *SAMGR_CreateFixedTaskPool(const TaskConfig *config, const char *name, uint8 size);
//启动任务池
int32 SAMGR_StartTaskPool(TaskPool *pool, const char *name);
//释放任务池
int32 SAMGR_ReleaseTaskPool(TaskPool *pool);
//引用任务池
TaskPool *SAMGR_ReferenceTaskPool(TaskPool *pool);
//获取当前的消息队列ID
MQueueId SAMGR_GetCurrentQueueID(void);
函数实现分析
任务池的创建
#ifndef MAX_TASK_SIZE
#define MAX_TASK_SIZE 0xFFFFFF //任务的最大数
#endif
//引用的最大数
#define MAX_REF_NUM 15
//消息处理的最大时间间隔
#define MSG_PROC_THRESHOLD (10 * 1000)
#define GET_REMAIN_TIME(time) ((0xFFFFFFFF - (time)) + 1)
//计算时间间隔
#define GET_INTERVAL(last, now) (((last) > (now)) ? (GET_REMAIN_TIME(last) + (now)) : ((now) - (last)))
typedef struct TaskPool TaskPool;
struct TaskPool {
MQueueId queueId; //消息队列ID
uint16 stackSize; //栈大小,用于配置线程的栈
uint8 priority; //任务的优先级,用于配置线程的优先级
uint8 size; //任务池的大小,维护的线程数
uint8 top; //标识tasks中的线程ID的个数
int8 ref; //引用数
ThreadId tasks[0]; //记录任务池下属的线程ID
};
//创建任务池
TaskPool *SAMGR_CreateFixedTaskPool(const TaskConfig *config, const char *name, uint8 size);
//启动任务池
int32 SAMGR_StartTaskPool(TaskPool *pool, const char *name);
//释放任务池
int32 SAMGR_ReleaseTaskPool(TaskPool *pool);
//引用任务池
TaskPool *SAMGR_ReferenceTaskPool(TaskPool *pool);
//获取当前的消息队列ID
MQueueId SAMGR_GetCurrentQueueID(void);
任务池的启动
/*
函数功能:启动任务池
函数参数:@pool:指向任务池的指针
@name:创建的线程名
函数返回:成功 返回EC_SUCCESS,失败 返回EC_INVALID
函数描述:向任务池中添加新创建的线程,创建的线程数等于pool->size值
*/
int32 SAMGR_StartTaskPool(TaskPool *pool, const char *name)
{
//参数检查
if (pool == NULL) {
return EC_INVALID;
}
//任务池中维护的线程数大于0时,返回EC_SUCCESS
if (pool->top > 0) {
return EC_SUCCESS;
}
//后续语句为pool->top小于或等于0才会执行
//配置线程属性
ThreadAttr attr = {name, pool->stackSize, pool->priority, 0, 0};
//创建pool->size个线程
while (pool->top < pool->size) {
/*
创建线程,运行的函数为TaskEntry
@1:创建的线程开始运行的函数地址
@2:运行函数需要的参数
@3:线程属性
*/
register ThreadId threadId = (ThreadId)THREAD_Create(TaskEntry, pool->queueId, &attr);
if (threadId == NULL) {
//记录错误日志
HILOG_ERROR(HILOG_MODULE_SAMGR, "Start Task<%s, %d, %d> failed!", name, pool->stackSize, pool->priority);
break;
}
//记录线程ID
pool->tasks[pool->top] = threadId;
++(pool->top);
}
return EC_SUCCESS;
}
释放任务池的内存
/*
函数功能:释放任务池的内存
函数返回:成功 返回EC_SUCCESS,失败 返回EC_INVALID
函数描述:更新任务池的引用数,若==0则构建消息类型为MSG_EXIT的exchange对象,发送到消息队列中,指示本任务池中的线程退出。并释放任务池。
*/
int32 SAMGR_ReleaseTaskPool(TaskPool *pool)
{
if (pool == NULL) {
return EC_INVALID;
}
//对任务池的引用计数减一
pool->ref--;
if (pool->ref == 0) {
//如果任务池未被其他对象引用,则回收资源
//初始化一个MSG_EXIT类型的exchange对象
Exchange exchange = {0};
//消息类型为MSG_EXIT,当任务池中的线程处理到消息队列中的这条消息时,会停止执行并退出
exchange.type = MSG_EXIT;
//将类型为MSG_EXIT的exchange对象发送到任务池绑定的消息队列中
QUEUE_Put(pool->queueId, &exchange, 0, DONT_WAIT);
//释放资源
SAMGR_Free(pool);
}
return EC_SUCCESS;
}
增加任务池的引用数
//引用对应的任务池,增加任务池的引用计数
TaskPool *SAMGR_ReferenceTaskPool(TaskPool *pool)
{
if (pool == NULL) {
return NULL;
}
if (pool->ref >= MAX_REF_NUM) {
//引用数超出最大值
return NULL;
}
//引用数自增
pool->ref++;
return pool;
}
task_manager剩下的部分实现将在下一篇进行分析。
写在最后
如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:
- 点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。
- 关注小编,同时可以期待后续文章ing🚀,不定期分享原创知识。
- 想要获取更多完整鸿蒙最新学习资源,请看下图提示: