// // Created by misaki on 2025/9/4. // #pragma once #include #include #include #include #include #include #include #include #include /** * @brief 线程配置结构体 * * 用于配置线程的各种属性,如名称、核心绑定、栈大小和优先级 */ struct ThreadConfig { std::string name = "thread"; // 线程名称 int core_id = -1; // 绑定核心ID (-1表示不绑定) int stack_size = 3072; // 栈大小 (字节) int priority = 5; // 优先级 bool inherit_cfg = false; // 是否允许子线程继承此配置 }; /** * @brief 线程管理类 * * 封装了ESP32上的线程创建和管理功能,支持普通函数、类成员函数和单例类成员函数 */ class ThreadManager { public: /** * @brief 创建并启动一个线程 * * @tparam Function 函数类型 * @tparam Args 参数类型 * @param config 线程配置 * @param func 要执行的函数 * @param args 函数参数 * @return std::thread 创建的线程对象 */ template static std::thread createThread(const ThreadConfig& config, Function&& func, Args&&... args) { // 创建ESP32线程配置 auto esp_cfg = create_esp_config(config); // 设置线程配置 esp_pthread_set_cfg(&esp_cfg); // 创建并启动线程 return std::thread(std::forward(func), std::forward(args)...); } /** * @brief 创建并启动一个执行类成员函数的线程 * * @tparam T 类类型 * @tparam Method 成员函数类型 * @tparam Args 参数类型 * @param config 线程配置 * @param obj 类对象指针 * @param method 成员函数指针 * @param args 函数参数 * @return std::thread 创建的线程对象 */ template static std::thread createMemberThread(const ThreadConfig& config, T* obj, Method&& method, Args&&... args) { // 使用lambda表达式包装成员函数调用 auto task = [obj, method, args...]() { (obj->*method)(args...); }; // 创建ESP32线程配置 auto esp_cfg = create_esp_config(config); // 设置线程配置 esp_pthread_set_cfg(&esp_cfg); // 创建并启动线程 return std::thread(task); } /** * @brief 创建并启动一个执行单例类成员函数的线程 * * @tparam T 单例类类型 * @tparam Method 成员函数类型 * @tparam Args 参数类型 * @param config 线程配置 * @param method 成员函数指针 * @param args 函数参数 * @return std::thread 创建的线程对象 */ template static std::thread createSingletonThread(const ThreadConfig& config, Method&& method, Args&&... args) { // 获取单例实例 T* instance = T::getInstance(); // 获取单例实例,注意这里就要求每个单例都要实现这个同名的静态函数 // 使用lambda表达式包装成员函数调用 auto task = [instance, method, args...]() { (instance->*method)(args...); }; // 创建ESP32线程配置 auto esp_cfg = create_esp_config(config); // 设置线程配置 esp_pthread_set_cfg(&esp_cfg); // 创建并启动线程 return std::thread(task); } /** * @brief 打印当前线程信息 * * @param extra 额外信息 */ static void printThreadInfo(const char *extra = nullptr) { std::stringstream ss; if (extra) { ss << extra; } ss << "Core id: " << xPortGetCoreID() << ", prio: " << uxTaskPriorityGet(nullptr) << ", minimum free stack: " << uxTaskGetStackHighWaterMark(nullptr) << " bytes."; ESP_LOGI(pcTaskGetName(nullptr), "%s", ss.str().c_str()); } private: /** * @brief 创建ESP32线程配置 * * @param config 线程配置 * @return esp_pthread_cfg_t ESP32线程配置 */ static esp_pthread_cfg_t create_esp_config(const ThreadConfig& config) { auto cfg = esp_pthread_get_default_config(); cfg.thread_name = config.name.c_str(); cfg.pin_to_core = config.core_id; cfg.stack_size = config.stack_size; cfg.prio = config.priority; cfg.inherit_cfg = config.inherit_cfg; return cfg; } };