线程池管理概念
线程池管理是一种多线程处理技术,它预先创建并维护一组线程(在FreeRTOS中称为任务),当有任务需要执行时,从池中取出空闲线程来执行,执行完成后线程返回池中等待下一次任务,而不是销毁线程。
FreeRTOS线程池管理特点
- 任务替代线程:FreeRTOS使用任务(task)而非线程(thread)
- 静态或动态创建:可以静态或动态方式创建任务池
- 队列管理:使用FreeRTOS队列进行任务调度
- 优先级管理:每个任务可以设置不同优先级
FreeRTOS线程池示例程序
以下是一个基于FreeRTOS的简单线程池管理示例:
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "timers.h"
#define POOL_SIZE 3 // 线程池大小
#define QUEUE_LENGTH 10 // 任务队列长度
// 任务函数原型
typedef void (*TaskFunction_t)(void *);
// 任务结构体
typedef struct {
TaskFunction_t function; // 任务函数
void *params; // 任务参数
} ThreadPoolTask_t;
// 线程池结构体
typedef struct {
TaskHandle_t tasks[POOL_SIZE]; // 任务句柄数组
QueueHandle_t taskQueue; // 任务队列
} ThreadPool_t;
// 工作线程函数
void workerTask(void *pvParameters) {
ThreadPool_t *pool = (ThreadPool_t *)pvParameters;
ThreadPoolTask_t task;
for (;;) {
// 从队列中获取任务
if (xQueueReceive(pool->taskQueue, &task, portMAX_DELAY) == pdPASS) {
// 执行任务
task.function(task.params);
}
}
}
// 初始化线程池
void threadPoolInit(ThreadPool_t *pool) {
// 创建任务队列
pool->taskQueue = xQueueCreate(QUEUE_LENGTH, sizeof(ThreadPoolTask_t));
// 创建工作线程
for (int i = 0; i < POOL_SIZE; i++) {
xTaskCreate(workerTask, "Worker", configMINIMAL_STACK_SIZE, pool, tskIDLE_PRIORITY + 1, &pool->tasks[i]);
}
}
// 添加任务到线程池
BaseType_t threadPoolAddTask(ThreadPool_t *pool, TaskFunction_t function, void *params) {
ThreadPoolTask_t task = {
.function = function,
.params = params
};
return xQueueSend(pool->taskQueue, &task, 0);
}
// 示例任务1
void exampleTask1(void *params) {
int *value = (int *)params;
printf("Task 1 processing value: %d\n", *value);
vTaskDelay(pdMS_TO_TICKS(100)); // 模拟工作
}
// 示例任务2
void exampleTask2(void *params) {
char *text = (char *)params;
printf("Task 2 processing text: %s\n", text);
vTaskDelay(pdMS_TO_TICKS(200)); // 模拟工作
}
void app_main() {
ThreadPool_t pool;
// 初始化线程池
threadPoolInit(&pool);
// 添加一些任务
int value1 = 42;
threadPoolAddTask(&pool, exampleTask1, &value1);
char text[] = "Hello FreeRTOS";
threadPoolAddTask(&pool, exampleTask2, text);
int value2 = 100;
threadPoolAddTask(&pool, exampleTask1, &value2);
// 让任务有时间执行
vTaskDelay(pdMS_TO_TICKS(1000));
}
示例说明
- 线程池结构:包含一个任务队列和一组工作线程(任务)
- 任务添加:通过
threadPoolAddTask
函数将任务添加到队列 - 工作线程:每个工作线程从队列中获取任务并执行
- 任务执行:示例中包含两个简单的任务函数
实际应用中的考虑
- 任务优先级:可以根据需要调整工作线程的优先级
- 队列满处理:添加任务时可能需要处理队列满的情况
- 资源清理:在不需要线程池时,需要正确删除任务和队列
- 错误处理:添加适当的错误检查和处理机制
这个示例展示了FreeRTOS中线程池管理的基本概念,可以根据实际需求进行扩展和优化。
----------------------------------------------------------------------------------------------------------------------
-----------以下是基于FreeRTOS线程池管理的流程图,使用Mermaid语法表示:---------------
graph TD
A[开始] --> B[初始化线程池]
B --> C[创建工作队列]
C --> D[创建工作线程1..N]
D --> E[线程池就绪]
E --> F{有新任务?}
F -->|是| G[添加任务到队列]
G --> H[队列是否满?]
H -->|否| I[任务入队成功]
H -->|是| J[执行拒绝策略]
F -->|否| K[继续等待]
subgraph 工作线程处理流程
L[工作线程1..N] --> M{队列有任务?}
M -->|是| N[取出任务]
N --> O[执行任务]
O --> P[任务完成]
P --> M
M -->|否| Q[等待新任务]
Q --> M
end
I --> M
K --> M
流程图说明:
-
初始化阶段:
- 创建任务队列(工作队列)
- 创建指定数量(N个)的工作线程
-
任务提交阶段:
- 当有新任务时,尝试加入队列
- 检查队列是否已满,未满则入队,已满则执行拒绝策略
-
任务执行阶段(工作线程循环):
- 每个工作线程不断检查队列
- 队列有任务时取出并执行
- 执行完成后继续检查队列
-
关键组件:
- 矩形框:处理步骤
- 菱形框:判断条件
- 子图:工作线程的独立循环流程
流程图特点:
-
展示了线程池的两个主要部分:
- 任务提交(生产者)
- 任务执行(消费者)
-
突出了FreeRTOS特有的元素:
- 工作队列(使用FreeRTOS队列实现)
- 工作线程(实际是FreeRTOS任务)
-
体现了线程池的核心机制:
- 线程复用
- 任务缓冲
- 并发控制