news 2026/2/25 13:06:40

Linux 应用模块化基础编写常用静态库与动态库

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Linux 应用模块化基础编写常用静态库与动态库

第一部分 对外接口

架构目录

tools_file/ ├── base │ ├── build │ │ ├── log.o │ │ ├── main.o │ │ ├── memory.o │ │ ├── test_common.o │ │ ├── test_memory.o │ │ ├── test_thread.o │ │ ├── thread_linux.o │ │ └── thread_memory_test │ ├── inc │ │ ├── common.h │ │ ├── log.h │ │ ├── memory.h │ │ ├── test_common.h │ │ └── thread_linux.h │ ├── Makefile │ ├── src │ │ ├── common.c │ │ ├── log.c │ │ ├── memory.c │ │ └── thread_linux.c │ └── test │ ├── main.c │ ├── test_common.c │ ├── test_memory.c │ ├── test_out.c │ └── test_thread.c ├── build │ ├── common.o │ ├── log.o │ ├── main.o │ ├── memory.o │ ├── test_common │ ├── test_common.o │ ├── test_memory.o │ ├── test_out.o │ ├── test_thread.o │ ├── thread_linux.o │ └── thread_memory_test └── lib ├── include │ ├── common.h │ ├── log.h │ ├── memory.h │ ├── test_common.h │ └── thread_linux.h ├── libcommon.a └── libcommon.so ​ 8 directories, 41 files ​

通用内存追踪开发,与通用线程接口封装。

common.h

/** * @file common.h * @brief 通用模块接口头文件 * * 提供统一的模块初始化、日志打印、错误处理等接口。 * 所有模块通过这个统一的接口进行访问。 */ ​ #ifndef COMMON_H #define COMMON_H ​ #include <stdbool.h> #include <stddef.h> ​ #ifdef __cplusplus extern "C" { #endif ​ /* ==================== 通用类型定义 ==================== */ ​ /** * @brief 错误码枚举 */ typedef enum { COMMON_SUCCESS = 0, /**< 操作成功 */ COMMON_ERROR_INIT, /**< 初始化失败 */ COMMON_ERROR_MEMORY, /**< 内存分配失败 */ COMMON_ERROR_PARAM, /**< 参数错误 */ COMMON_ERROR_SYSTEM, /**< 系统错误 */ COMMON_ERROR_NOT_INIT, /**< 模块未初始化 */ COMMON_ERROR_ALREADY_INIT, /**< 模块已初始化 */ COMMON_ERROR_RESOURCE, /**< 资源错误 */ COMMON_ERROR_TIMEOUT /**< 操作超时 */ } common_error_t; ​ /** * @brief 日志级别枚举 */ typedef enum { LOG_LEVEL_DEBUG = 0, /**< 调试信息 */ LOG_LEVEL_INFO, /**< 一般信息 */ LOG_LEVEL_WARN, /**< 警告信息 */ LOG_LEVEL_ERROR, /**< 错误信息 */ LOG_LEVEL_FATAL /**< 致命错误 */ } log_level_t; ​ /** * @brief 模块ID枚举 */ typedef enum { MODULE_COMMON = 0, /**< 通用模块 */ MODULE_LOG, /**< 日志模块 */ MODULE_MEMORY, /**< 内存模块 */ MODULE_THREAD, /**< 线程模块 */ MODULE_TEST /**< 测试模块 */ } module_id_t; ​ /* ==================== 初始化与销毁接口 ==================== */ ​ /** * @brief 初始化所有模块 * * 一次性初始化日志、内存、线程等所有模块。 * * @return common_error_t 错误码 */ common_error_t common_init_all(void); ​ /** * @brief 销毁所有模块 * * 按正确顺序销毁所有模块,确保资源正确释放。 */ void common_destroy_all(void); ​ /** * @brief 检查所有模块是否已初始化 * * @return true 所有模块已初始化 * @return false 有模块未初始化 */ bool common_is_all_initialized(void); ​ /** * @brief 获取模块初始化状态 * * @param module 模块ID * @return true 模块已初始化 * @return false 模块未初始化 */ bool common_module_is_initialized(module_id_t module); ​ /* ==================== 线程安全的日志接口 ==================== */ ​ /** * @brief 打印日志(线程安全) * * 使用互斥锁保护,确保多线程环境下的日志输出安全。 * * @param level 日志级别 * @param module 模块名称 * @param format 格式字符串 * @param ... 可变参数 */ void common_log(log_level_t level, const char* module, const char* format, ...) __attribute__((format(printf, 3, 4))); ​ /** * @brief 调试级别日志 * * @param module 模块名称 * @param format 格式字符串 * @param ... 可变参数 */ #define LOG_DEBUG(module, ...) \ common_log(LOG_LEVEL_DEBUG, module, __VA_ARGS__) ​ /** * @brief 信息级别日志 * * @param module 模块名称 * @param format 格式字符串 * @param ... 可变参数 */ #define LOG_INFO(module, ...) \ common_log(LOG_LEVEL_INFO, module, __VA_ARGS__) ​ /** * @brief 警告级别日志 * * @param module 模块名称 * @param format 格式字符串 * @param ... 可变参数 */ #define LOG_WARN(module, ...) \ common_log(LOG_LEVEL_WARN, module, __VA_ARGS__) ​ /** * @brief 错误级别日志 * * @param module 模块名称 * @param format 格式字符串 * @param ... 可变参数 */ #define LOG_ERROR(module, ...) \ common_log(LOG_LEVEL_ERROR, module, __VA_ARGS__) ​ /** * @brief 致命错误级别日志 * * @param module 模块名称 * @param format 格式字符串 * @param ... 可变参数 */ #define LOG_FATAL(module, ...) \ common_log(LOG_LEVEL_FATAL, module, __VA_ARGS__) ​ /** * @brief 设置日志级别 * * @param level 日志级别 */ void common_log_set_level(log_level_t level); ​ /** * @brief 获取当前日志级别 * * @return log_level_t 当前日志级别 */ log_level_t common_log_get_level(void); ​ /** * @brief 启用/禁用控制台输出 * * @param enable true启用,false禁用 */ void common_log_set_console_output(bool enable); ​ /* ==================== 错误处理接口 ==================== */ ​ /** * @brief 获取错误码描述 * * @param error 错误码 * @return const char* 错误描述字符串 */ const char* common_strerror(common_error_t error); ​ /** * @brief 获取最后错误码 * * @return common_error_t 最后错误码 */ common_error_t common_get_last_error(void); ​ /** * @brief 清除错误状态 */ void common_clear_error(void); ​ /* ==================== 内存管理接口 ==================== */ ​ /** * @brief 分配内存 * * @param size 分配大小 * @return void* 分配的内存指针 */ void* common_malloc(size_t size); ​ /** * @brief 分配并清零内存 * * @param nmemb 元素数量 * @param size 元素大小 * @return void* 分配的内存指针 */ void* common_calloc(size_t nmemb, size_t size); ​ /** * @brief 重新分配内存 * * @param ptr 原内存指针 * @param size 新大小 * @return void* 重新分配的内存指针 */ void* common_realloc(void* ptr, size_t size); ​ /** * @brief 释放内存 * * @param ptr 内存指针 */ void common_free(void* ptr); ​ /** * @brief 检查内存泄漏 * * @return size_t 泄漏的内存块数量 */ size_t common_check_memory_leaks(void); ​ /** * @brief 打印内存统计信息 */ void common_print_memory_stats(void); ​ /* ==================== 线程管理接口 ==================== */ ​ /** * @brief 创建线程 * * @param func 线程函数 * @param arg 线程参数 * @param name 线程名称 * @return void* 线程句柄 */ void* common_thread_create(void* (*func)(void*), void* arg, const char* name); ​ /** * @brief 等待线程结束 * * @param thread 线程句柄 * @param retval 接收返回值 * @return common_error_t 错误码 */ common_error_t common_thread_join(void* thread, void** retval); ​ /** * @brief 分离线程 * * @param thread 线程句柄 * @return common_error_t 错误码 */ common_error_t common_thread_detach(void* thread); ​ /** * @brief 睡眠指定毫秒数 * * @param milliseconds 毫秒数 */ void common_sleep(unsigned int milliseconds); ​ /** * @brief 让出CPU */ void common_thread_yield(void); ​ /* ==================== 线程管理接口 ==================== */ ​ /** * @brief 线程属性结构 */ typedef struct { size_t stack_size; /**< 栈大小(字节),0表示默认值 */ bool detach_state; /**< 是否分离(true:分离, false:可连接) */ int priority; /**< 线程优先级 */ } common_thread_attr_t; ​ /** * @brief 创建线程 * * @param func 线程函数 * @param arg 线程参数 * @param name 线程名称 * @return void* 线程句柄,失败返回NULL */ void* common_thread_create(void* (*func)(void*), void* arg, const char* name); ​ /** * @brief 创建带属性的线程 * * @param func 线程函数 * @param arg 线程参数 * @param name 线程名称 * @param attr 线程属性,NULL表示默认属性 * @return void* 线程句柄,失败返回NULL */ void* common_thread_create_ex(void* (*func)(void*), void* arg, const char* name, const common_thread_attr_t* attr); ​ /** * @brief 等待线程结束 * * @param thread 线程句柄 * @param retval 接收返回值 * @return common_error_t 错误码 */ common_error_t common_thread_join(void* thread, void** retval); ​ /** * @brief 分离线程 * * @param thread 线程句柄 * @return common_error_t 错误码 */ common_error_t common_thread_detach(void* thread); ​ /** * @brief 取消线程 * * @param thread 线程句柄 * @return common_error_t 错误码 */ common_error_t common_thread_cancel(void* thread); ​ /** * @brief 获取当前线程句柄 * * @return void* 当前线程句柄 */ void* common_thread_self(void); ​ /** * @brief 设置线程名称 * * @param thread 线程句柄 * @param name 线程名称 * @return common_error_t 错误码 */ common_error_t common_thread_set_name(void* thread, const char* name); ​ /** * @brief 获取线程名称 * * @param thread 线程句柄 * @param name 输出缓冲区 * @param size 缓冲区大小 * @return common_error_t 错误码 */ common_error_t common_thread_get_name(void* thread, char* name, size_t size); ​ /** * @brief 销毁线程句柄 * * @param thread 线程句柄 * @return common_error_t 错误码 */ common_error_t common_thread_destroy(void* thread); ​ /** * @brief 睡眠指定毫秒数 * * @param milliseconds 毫秒数 */ void common_sleep(unsigned int milliseconds); ​ /** * @brief 让出CPU */ void common_thread_yield(void); ​ /** * @brief 获取线程ID * * @param thread 线程句柄 * @return unsigned long 线程ID,失败返回0 */ unsigned long common_thread_get_id(void* thread); ​ /* ==================== 互斥锁接口 ==================== */ ​ /** * @brief 互斥锁句柄 */ typedef void* common_mutex_t; ​ /** * @brief 创建互斥锁 * * @return common_mutex_t 互斥锁句柄,失败返回NULL */ common_mutex_t common_mutex_create(void); ​ /** * @brief 销毁互斥锁 * * @param mutex 互斥锁句柄 * @return common_error_t 错误码 */ common_error_t common_mutex_destroy(common_mutex_t mutex); ​ /** * @brief 锁定互斥锁 * * @param mutex 互斥锁句柄 * @return common_error_t 错误码 */ common_error_t common_mutex_lock(common_mutex_t mutex); ​ /** * @brief 尝试锁定互斥锁 * * @param mutex 互斥锁句柄 * @return common_error_t 成功返回COMMON_SUCCESS,被锁定返回COMMON_ERROR_TIMEOUT */ common_error_t common_mutex_trylock(common_mutex_t mutex); ​ /** * @brief 解锁互斥锁 * * @param mutex 互斥锁句柄 * @return common_error_t 错误码 */ common_error_t common_mutex_unlock(common_mutex_t mutex); ​ /* ==================== 条件变量接口 ==================== */ ​ /** * @brief 条件变量句柄 */ typedef void* common_cond_t; ​ /** * @brief 创建条件变量 * * @return common_cond_t 条件变量句柄,失败返回NULL */ common_cond_t common_cond_create(void); ​ /** * @brief 销毁条件变量 * * @param cond 条件变量句柄 * @return common_error_t 错误码 */ common_error_t common_cond_destroy(common_cond_t cond); ​ /** * @brief 等待条件变量 * * @param cond 条件变量句柄 * @param mutex 互斥锁句柄 * @return common_error_t 错误码 */ common_error_t common_cond_wait(common_cond_t cond, common_mutex_t mutex); ​ /** * @brief 带超时等待条件变量 * * @param cond 条件变量句柄 * @param mutex 互斥锁句柄 * @param timeout_ms 超时时间(毫秒) * @return common_error_t 超时返回COMMON_ERROR_TIMEOUT */ common_error_t common_cond_timedwait(common_cond_t cond, common_mutex_t mutex, unsigned int timeout_ms); ​ /** * @brief 唤醒一个等待条件变量的线程 * * @param cond 条件变量句柄 * @return common_error_t 错误码 */ common_error_t common_cond_signal(common_cond_t cond); ​ /** * @brief 唤醒所有等待条件变量的线程 * * @param cond 条件变量句柄 * @return common_error_t 错误码 */ common_error_t common_cond_broadcast(common_cond_t cond); ​ /* ==================== 信号量接口 ==================== */ ​ /** * @brief 信号量句柄 */ typedef void* common_sem_t; ​ /** * @brief 创建信号量 * * @param initial_value 初始值 * @return common_sem_t 信号量句柄,失败返回NULL */ common_sem_t common_sem_create(unsigned int initial_value); ​ /** * @brief 销毁信号量 * * @param sem 信号量句柄 * @return common_error_t 错误码 */ common_error_t common_sem_destroy(common_sem_t sem); ​ /** * @brief 等待信号量 * * @param sem 信号量句柄 * @return common_error_t 错误码 */ common_error_t common_sem_wait(common_sem_t sem); ​ /** * @brief 尝试等待信号量 * * @param sem 信号量句柄 * @return common_error_t 信号量为0返回COMMON_ERROR_TIMEOUT */ common_error_t common_sem_trywait(common_sem_t sem); ​ /** * @brief 带超时等待信号量 * * @param sem 信号量句柄 * @param timeout_ms 超时时间(毫秒) * @return common_error_t 超时返回COMMON_ERROR_TIMEOUT */ common_error_t common_sem_timedwait(common_sem_t sem, unsigned int timeout_ms); ​ /** * @brief 释放信号量 * * @param sem 信号量句柄 * @return common_error_t 错误码 */ common_error_t common_sem_post(common_sem_t sem); ​ /** * @brief 获取信号量当前值 * * @param sem 信号量句柄 * @param value 输出参数,接收信号量值 * @return common_error_t 错误码 */ common_error_t common_sem_getvalue(common_sem_t sem, int* value); ​ ​ #ifdef __cplusplus } #endif ​ #endif /* COMMON_H */ ​

common.c

/** * @file common.c * @brief 通用模块接口实现 * * 提供统一的模块管理、线程安全日志等功能。 */ ​ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdarg.h> #include <time.h> #include <pthread.h> #include "common.h" #include "log.h" #include "memory.h" #include "thread_linux.h" ​ /** @brief 通用模块的日志模块名称 */ #define COMMON_MODULE_NAME "COMMON" ​ /** @brief 默认日志缓冲区大小 */ #define DEFAULT_LOG_BUFFER_SIZE 8192 ​ /** @brief 全局互斥锁,用于保护日志输出 */ static pthread_mutex_t g_log_mutex = PTHREAD_MUTEX_INITIALIZER; ​ /** @brief 全局互斥锁,用于保护日志输出 */ //static pthread_mutex_t g_log_mutex = PTHREAD_MUTEX_INITIALIZER; ​ /** @brief 模块初始化状态数组 */ static struct { bool modules[5]; /**< 各模块初始化状态 */ common_error_t last_error; /**< 最后错误码 */ bool all_initialized; /**< 所有模块是否已初始化 */ } g_common_state = { .modules = {false}, .last_error = COMMON_SUCCESS, .all_initialized = false }; ​ /** @brief 模块名称映射表 */ static const char* g_module_names[] = { "COMMON", "LOG", "MEMORY", "THREAD", "TEST" }; ​ /** * @brief 设置错误码 * * @param error 错误码 */ static void set_error(common_error_t error) { g_common_state.last_error = error; } ​ /** * @brief 获取当前时间字符串 * * @param buffer 时间字符串缓冲区 * @param size 缓冲区大小 */ static void get_current_time_str(char* buffer, size_t size) { if (buffer == NULL || size == 0) { return; } time_t now = time(NULL); struct tm* tm_info = localtime(&now); strftime(buffer, size, "%H:%M:%S", tm_info); } ​ /** * @brief 获取日志级别字符串 * * @param level 日志级别 * @return const char* 级别字符串 */ static const char* get_log_level_str(log_level_t level) { switch (level) { case LOG_LEVEL_DEBUG: return "DEBUG"; case LOG_LEVEL_INFO: return "INFO"; case LOG_LEVEL_WARN: return "WARN"; case LOG_LEVEL_ERROR: return "ERROR"; case LOG_LEVEL_FATAL: return "FATAL"; default: return "UNKNOWN"; } } ​ /* ==================== 初始化与销毁实现 ==================== */ ​ /** * @brief 初始化所有模块 * * @return common_error_t 错误码 */ common_error_t common_init_all(void) { if (g_common_state.all_initialized) { LOG_WARN(COMMON_MODULE_NAME, "所有模块已经初始化"); set_error(COMMON_ERROR_ALREADY_INIT); return COMMON_SUCCESS; /* 已经初始化也算成功 */ } LOG_INFO(COMMON_MODULE_NAME, "开始初始化所有模块..."); /* 1. 初始化日志模块 */ LOG_INFO(COMMON_MODULE_NAME, "初始化日志模块..."); if (!log_init(DEFAULT_LOG_BUFFER_SIZE)) { LOG_ERROR(COMMON_MODULE_NAME, "初始化日志模块失败"); set_error(COMMON_ERROR_INIT); return COMMON_ERROR_INIT; } log_set_console_output(true); log_set_level(LOG_LEVEL_INFO); g_common_state.modules[MODULE_LOG] = true; LOG_INFO(COMMON_MODULE_NAME, "日志模块初始化成功"); /* 2. 初始化内存模块 */ LOG_INFO(COMMON_MODULE_NAME, "初始化内存模块..."); if (!memory_init()) { LOG_ERROR(COMMON_MODULE_NAME, "初始化内存模块失败"); log_destroy(); g_common_state.modules[MODULE_LOG] = false; set_error(COMMON_ERROR_INIT); return COMMON_ERROR_INIT; } g_common_state.modules[MODULE_MEMORY] = true; LOG_INFO(COMMON_MODULE_NAME, "内存模块初始化成功"); /* 3. 初始化线程模块 */ LOG_INFO(COMMON_MODULE_NAME, "初始化线程模块..."); thread_error_t thread_err = thread_module_init(); if (thread_err != THREAD_SUCCESS) { LOG_ERROR(COMMON_MODULE_NAME, "初始化线程模块失败: %d", thread_err); memory_destroy(); log_destroy(); g_common_state.modules[MODULE_MEMORY] = false; g_common_state.modules[MODULE_LOG] = false; set_error(COMMON_ERROR_INIT); return COMMON_ERROR_INIT; } g_common_state.modules[MODULE_THREAD] = true; LOG_INFO(COMMON_MODULE_NAME, "线程模块初始化成功"); /* 4. 通用模块自身 */ g_common_state.modules[MODULE_COMMON] = true; g_common_state.all_initialized = true; set_error(COMMON_SUCCESS); LOG_INFO(COMMON_MODULE_NAME, "所有模块初始化完成"); return COMMON_SUCCESS; } ​ /** * @brief 销毁所有模块 */ void common_destroy_all(void) { if (!g_common_state.all_initialized) { LOG_WARN(COMMON_MODULE_NAME, "模块未初始化,无需销毁"); return; } LOG_INFO(COMMON_MODULE_NAME, "开始销毁所有模块..."); /* 按依赖关系反向销毁 */ /* 1. 销毁线程模块 */ if (g_common_state.modules[MODULE_THREAD]) { LOG_INFO(COMMON_MODULE_NAME, "销毁线程模块..."); thread_module_destroy(); g_common_state.modules[MODULE_THREAD] = false; LOG_INFO(COMMON_MODULE_NAME, "线程模块销毁完成"); } /* 2. 销毁内存模块(会检查泄漏) */ if (g_common_state.modules[MODULE_MEMORY]) { LOG_INFO(COMMON_MODULE_NAME, "销毁内存模块..."); memory_destroy(); g_common_state.modules[MODULE_MEMORY] = false; LOG_INFO(COMMON_MODULE_NAME, "内存模块销毁完成"); } /* 3. 销毁日志模块 */ if (g_common_state.modules[MODULE_LOG]) { LOG_INFO(COMMON_MODULE_NAME, "销毁日志模块..."); log_destroy(); g_common_state.modules[MODULE_LOG] = false; LOG_INFO(COMMON_MODULE_NAME, "日志模块销毁完成"); } /* 4. 通用模块自身 */ g_common_state.modules[MODULE_COMMON] = false; g_common_state.all_initialized = false; set_error(COMMON_SUCCESS); LOG_INFO(COMMON_MODULE_NAME, "所有模块销毁完成"); } ​ /** * @brief 检查所有模块是否已初始化 * * @return true 所有模块已初始化 * @return false 有模块未初始化 */ bool common_is_all_initialized(void) { return g_common_state.all_initialized; } ​ /** * @brief 获取模块初始化状态 * * @param module 模块ID * @return true 模块已初始化 * @return false 模块未初始化 */ bool common_module_is_initialized(module_id_t module) { if (module < 0 || module >= sizeof(g_common_state.modules)/sizeof(g_common_state.modules[0])) { return false; } return g_common_state.modules[module]; } ​ /* ==================== 线程安全的日志接口实现 ==================== */ ​ /** * @brief 打印日志(线程安全) * * 这是对 base_log 的线程安全封装。 * base_log 已经实现了所有输出逻辑。 */ void common_log(log_level_t level, const char* module, const char* format, ...) { /* 参数检查 */ if (format == NULL) { return; } /* 日志级别过滤(可选,因为 base_log 也会检查) */ log_level_t current_level = common_log_get_level(); if (level < current_level) { return; } /* 加锁保护(确保多线程安全) */ pthread_mutex_lock(&g_log_mutex); /* 直接调用 base_log,它已经实现了所有输出逻辑 */ va_list args; va_start(args, format); /* 注意:base_log 不支持 va_list,需要我们自己包装 */ /* 方法1:如果支持 va_list 版本 */ /* base_log_va(level, module, format, args); */ /* 方法2:如果不支持 va_list,需要格式化字符串 */ char message[1024]; vsnprintf(message, sizeof(message), format, args); base_log((log_base_level_t)level, module, "%s", message); va_end(args); /* 解锁 */ pthread_mutex_unlock(&g_log_mutex); } ​ /** * @brief 设置日志级别 */ void common_log_set_level(log_level_t level) { log_set_level(level); } ​ /** * @brief 获取当前日志级别 */ log_level_t common_log_get_level(void) { return log_get_level(); } ​ /** * @brief 启用/禁用控制台输出 */ void common_log_set_console_output(bool enable) { log_set_console_output(enable); } ​ /* ==================== 错误处理接口实现 ==================== */ ​ /** * @brief 获取错误码描述 */ const char* common_strerror(common_error_t error) { switch (error) { case COMMON_SUCCESS: return "Success"; case COMMON_ERROR_INIT: return "Initialization failed"; case COMMON_ERROR_MEMORY: return "Memory allocation failed"; case COMMON_ERROR_PARAM: return "Invalid parameter"; case COMMON_ERROR_SYSTEM: return "System error"; case COMMON_ERROR_NOT_INIT: return "Module not initialized"; case COMMON_ERROR_ALREADY_INIT: return "Module already initialized"; case COMMON_ERROR_RESOURCE: return "Resource error"; case COMMON_ERROR_TIMEOUT: return "Operation timeout"; default: return "Unknown error"; } } ​ /** * @brief 获取最后错误码 */ common_error_t common_get_last_error(void) { return g_common_state.last_error; } ​ /** * @brief 清除错误状态 */ void common_clear_error(void) { g_common_state.last_error = COMMON_SUCCESS; } ​ /* ==================== 内存管理接口实现 ==================== */ ​ /** * @brief 分配内存 */ void* common_malloc(size_t size) { if (!g_common_state.modules[MODULE_MEMORY]) { LOG_ERROR(COMMON_MODULE_NAME, "内存模块未初始化"); set_error(COMMON_ERROR_NOT_INIT); return malloc(size); /* 回退到标准malloc */ } void* ptr = memory_malloc(size); if (ptr == NULL) { set_error(COMMON_ERROR_MEMORY); } else { set_error(COMMON_SUCCESS); } return ptr; } ​ /** * @brief 分配并清零内存 */ void* common_calloc(size_t nmemb, size_t size) { if (!g_common_state.modules[MODULE_MEMORY]) { LOG_ERROR(COMMON_MODULE_NAME, "内存模块未初始化"); set_error(COMMON_ERROR_NOT_INIT); return calloc(nmemb, size); } void* ptr = memory_calloc(nmemb, size); if (ptr == NULL) { set_error(COMMON_ERROR_MEMORY); } else { set_error(COMMON_SUCCESS); } return ptr; } ​ /** * @brief 重新分配内存 */ void* common_realloc(void* ptr, size_t size) { if (!g_common_state.modules[MODULE_MEMORY]) { LOG_ERROR(COMMON_MODULE_NAME, "内存模块未初始化"); set_error(COMMON_ERROR_NOT_INIT); return realloc(ptr, size); } void* new_ptr = memory_realloc(ptr, size); if (new_ptr == NULL && size > 0) { set_error(COMMON_ERROR_MEMORY); } else { set_error(COMMON_SUCCESS); } return new_ptr; } ​ /** * @brief 释放内存 */ void common_free(void* ptr) { if (!g_common_state.modules[MODULE_MEMORY]) { LOG_ERROR(COMMON_MODULE_NAME, "内存模块未初始化"); set_error(COMMON_ERROR_NOT_INIT); free(ptr); return; } memory_free(ptr); set_error(COMMON_SUCCESS); } ​ /** * @brief 检查内存泄漏 */ size_t common_check_memory_leaks(void) { if (!g_common_state.modules[MODULE_MEMORY]) { LOG_ERROR(COMMON_MODULE_NAME, "内存模块未初始化"); set_error(COMMON_ERROR_NOT_INIT); return 0; } size_t leaks = memory_check_leaks(); set_error(COMMON_SUCCESS); return leaks; } ​ /** * @brief 打印内存统计信息 */ void common_print_memory_stats(void) { if (!g_common_state.modules[MODULE_MEMORY]) { LOG_ERROR(COMMON_MODULE_NAME, "内存模块未初始化"); return; } memory_print_stats(); } ​ /* ==================== 线程管理接口实现 ==================== */ ​ /** * @brief 创建线程 */ /*void* common_thread_create(void* (*func)(void*), void* arg, const char* name) { if (!g_common_state.modules[MODULE_THREAD]) { LOG_ERROR(COMMON_MODULE_NAME, "线程模块未初始化"); set_error(COMMON_ERROR_NOT_INIT); return NULL; } if (func == NULL) { LOG_ERROR(COMMON_MODULE_NAME, "线程函数不能为NULL"); set_error(COMMON_ERROR_PARAM); return NULL; } thread_handle_t thread; thread_error_t err = thread_create(func, arg, name, &thread); if (err != THREAD_SUCCESS) { LOG_ERROR(COMMON_MODULE_NAME, "创建线程失败: %s", thread_strerror(err)); set_error(COMMON_ERROR_SYSTEM); return NULL; } set_error(COMMON_SUCCESS); return thread; }*/ ​ /** * @brief 等待线程结束 */ common_error_t common_thread_join(void* thread, void** retval) { if (!g_common_state.modules[MODULE_THREAD]) { LOG_ERROR(COMMON_MODULE_NAME, "线程模块未初始化"); set_error(COMMON_ERROR_NOT_INIT); return COMMON_ERROR_NOT_INIT; } if (thread == NULL) { LOG_ERROR(COMMON_MODULE_NAME, "线程句柄不能为NULL"); set_error(COMMON_ERROR_PARAM); return COMMON_ERROR_PARAM; } thread_error_t err = thread_join((thread_handle_t)thread, retval); if (err != THREAD_SUCCESS) { LOG_ERROR(COMMON_MODULE_NAME, "等待线程失败: %s", thread_strerror(err)); set_error(COMMON_ERROR_SYSTEM); return COMMON_ERROR_SYSTEM; } set_error(COMMON_SUCCESS); return COMMON_SUCCESS; } ​ /** * @brief 分离线程 */ common_error_t common_thread_detach(void* thread) { if (!g_common_state.modules[MODULE_THREAD]) { LOG_ERROR(COMMON_MODULE_NAME, "线程模块未初始化"); set_error(COMMON_ERROR_NOT_INIT); return COMMON_ERROR_NOT_INIT; } if (thread == NULL) { LOG_ERROR(COMMON_MODULE_NAME, "线程句柄不能为NULL"); set_error(COMMON_ERROR_PARAM); return COMMON_ERROR_PARAM; } thread_error_t err = thread_detach((thread_handle_t)thread); if (err != THREAD_SUCCESS) { LOG_ERROR(COMMON_MODULE_NAME, "分离线程失败: %s", thread_strerror(err)); set_error(COMMON_ERROR_SYSTEM); return COMMON_ERROR_SYSTEM; } set_error(COMMON_SUCCESS); return COMMON_SUCCESS; } ​ /** * @brief 睡眠指定毫秒数 */ void common_sleep(unsigned int milliseconds) { thread_sleep(milliseconds); } ​ /** * @brief 让出CPU */ void common_thread_yield(void) { thread_yield(); } ​ /* ==================== 线程管理接口实现 ==================== */ ​ /** * @brief 创建线程 */ void* common_thread_create(void* (*func)(void*), void* arg, const char* name) { return common_thread_create_ex(func, arg, name, NULL); } ​ /** * @brief 创建带属性的线程 */ void* common_thread_create_ex(void* (*func)(void*), void* arg, const char* name, const common_thread_attr_t* attr) { if (!g_common_state.modules[MODULE_THREAD]) { LOG_ERROR(COMMON_MODULE_NAME, "线程模块未初始化"); set_error(COMMON_ERROR_NOT_INIT); return NULL; } if (func == NULL) { LOG_ERROR(COMMON_MODULE_NAME, "线程函数不能为NULL"); set_error(COMMON_ERROR_PARAM); return NULL; } thread_handle_t thread; thread_error_t err; if (attr != NULL) { /* 使用指定属性创建线程 */ err = thread_create_ex(func, arg, name, attr->stack_size, attr->detach_state, &thread); } else { /* 使用默认属性创建线程 */ err = thread_create(func, arg, name, &thread); } if (err != THREAD_SUCCESS) { LOG_ERROR(COMMON_MODULE_NAME, "创建线程失败: %s", thread_strerror(err)); set_error(COMMON_ERROR_SYSTEM); return NULL; } set_error(COMMON_SUCCESS); return (void*)thread; } ​ /** * @brief 取消线程 */ common_error_t common_thread_cancel(void* thread) { if (!g_common_state.modules[MODULE_THREAD]) { LOG_ERROR(COMMON_MODULE_NAME, "线程模块未初始化"); set_error(COMMON_ERROR_NOT_INIT); return COMMON_ERROR_NOT_INIT; } if (thread == NULL) { LOG_ERROR(COMMON_MODULE_NAME, "线程句柄不能为NULL"); set_error(COMMON_ERROR_PARAM); return COMMON_ERROR_PARAM; } thread_error_t err = thread_cancel((thread_handle_t)thread); if (err != THREAD_SUCCESS) { LOG_ERROR(COMMON_MODULE_NAME, "取消线程失败: %s", thread_strerror(err)); set_error(COMMON_ERROR_SYSTEM); return COMMON_ERROR_SYSTEM; } set_error(COMMON_SUCCESS); return COMMON_SUCCESS; } ​ /** * @brief 获取当前线程句柄 */ void* common_thread_self(void) { if (!g_common_state.modules[MODULE_THREAD]) { LOG_ERROR(COMMON_MODULE_NAME, "线程模块未初始化"); set_error(COMMON_ERROR_NOT_INIT); return NULL; } thread_handle_t self = thread_self(); if (self == NULL) { set_error(COMMON_ERROR_SYSTEM); } else { set_error(COMMON_SUCCESS); } return (void*)self; } ​ /** * @brief 设置线程名称 */ common_error_t common_thread_set_name(void* thread, const char* name) { if (!g_common_state.modules[MODULE_THREAD]) { LOG_ERROR(COMMON_MODULE_NAME, "线程模块未初始化"); set_error(COMMON_ERROR_NOT_INIT); return COMMON_ERROR_NOT_INIT; } if (thread == NULL || name == NULL || name[0] == '\0') { LOG_ERROR(COMMON_MODULE_NAME, "线程句柄或名称无效"); set_error(COMMON_ERROR_PARAM); return COMMON_ERROR_PARAM; } thread_error_t err = thread_set_name((thread_handle_t)thread, name); if (err != THREAD_SUCCESS) { LOG_ERROR(COMMON_MODULE_NAME, "设置线程名称失败: %s", thread_strerror(err)); set_error(COMMON_ERROR_SYSTEM); return COMMON_ERROR_SYSTEM; } set_error(COMMON_SUCCESS); return COMMON_SUCCESS; } ​ /** * @brief 获取线程名称 */ common_error_t common_thread_get_name(void* thread, char* name, size_t size) { if (!g_common_state.modules[MODULE_THREAD]) { LOG_ERROR(COMMON_MODULE_NAME, "线程模块未初始化"); set_error(COMMON_ERROR_NOT_INIT); return COMMON_ERROR_NOT_INIT; } if (thread == NULL || name == NULL || size == 0) { LOG_ERROR(COMMON_MODULE_NAME, "参数无效"); set_error(COMMON_ERROR_PARAM); return COMMON_ERROR_PARAM; } thread_error_t err = thread_get_name((thread_handle_t)thread, name, size); if (err != THREAD_SUCCESS) { LOG_ERROR(COMMON_MODULE_NAME, "获取线程名称失败: %s", thread_strerror(err)); set_error(COMMON_ERROR_SYSTEM); return COMMON_ERROR_SYSTEM; } set_error(COMMON_SUCCESS); return COMMON_SUCCESS; } ​ /** * @brief 销毁线程句柄 */ common_error_t common_thread_destroy(void* thread) { if (!g_common_state.modules[MODULE_THREAD]) { LOG_ERROR(COMMON_MODULE_NAME, "线程模块未初始化"); set_error(COMMON_ERROR_NOT_INIT); return COMMON_ERROR_NOT_INIT; } if (thread == NULL) { LOG_ERROR(COMMON_MODULE_NAME, "线程句柄不能为NULL"); set_error(COMMON_ERROR_PARAM); return COMMON_ERROR_PARAM; } thread_error_t err = thread_destroy((thread_handle_t)thread); if (err != THREAD_SUCCESS) { LOG_ERROR(COMMON_MODULE_NAME, "销毁线程句柄失败: %s", thread_strerror(err)); set_error(COMMON_ERROR_SYSTEM); return COMMON_ERROR_SYSTEM; } set_error(COMMON_SUCCESS); return COMMON_SUCCESS; } ​ /** * @brief 获取线程ID */ unsigned long common_thread_get_id(void* thread) { if (!g_common_state.modules[MODULE_THREAD]) { LOG_ERROR(COMMON_MODULE_NAME, "线程模块未初始化"); set_error(COMMON_ERROR_NOT_INIT); return 0; } if (thread == NULL) { LOG_ERROR(COMMON_MODULE_NAME, "线程句柄不能为NULL"); set_error(COMMON_ERROR_PARAM); return 0; } /* 注意:这里需要在线程模块中增加获取线程ID的函数 */ /* 暂时返回0,表示不支持 */ LOG_WARN(COMMON_MODULE_NAME, "获取线程ID功能未实现"); set_error(COMMON_ERROR_RESOURCE); return 0; } ​ /* ==================== 互斥锁接口实现 ==================== */ ​ /** * @brief 创建互斥锁 */ common_mutex_t common_mutex_create(void) { if (!g_common_state.modules[MODULE_THREAD]) { LOG_ERROR(COMMON_MODULE_NAME, "线程模块未初始化"); set_error(COMMON_ERROR_NOT_INIT); return NULL; } thread_mutex_t mutex; thread_error_t err = thread_mutex_create(&mutex); if (err != THREAD_SUCCESS) { LOG_ERROR(COMMON_MODULE_NAME, "创建互斥锁失败: %s", thread_strerror(err)); set_error(COMMON_ERROR_SYSTEM); return NULL; } set_error(COMMON_SUCCESS); return (common_mutex_t)mutex; } ​ /** * @brief 销毁互斥锁 */ common_error_t common_mutex_destroy(common_mutex_t mutex) { if (!g_common_state.modules[MODULE_THREAD]) { LOG_ERROR(COMMON_MODULE_NAME, "线程模块未初始化"); set_error(COMMON_ERROR_NOT_INIT); return COMMON_ERROR_NOT_INIT; } if (mutex == NULL) { LOG_ERROR(COMMON_MODULE_NAME, "互斥锁句柄不能为NULL"); set_error(COMMON_ERROR_PARAM); return COMMON_ERROR_PARAM; } thread_error_t err = thread_mutex_destroy((thread_mutex_t)mutex); if (err != THREAD_SUCCESS) { LOG_ERROR(COMMON_MODULE_NAME, "销毁互斥锁失败: %s", thread_strerror(err)); set_error(COMMON_ERROR_SYSTEM); return COMMON_ERROR_SYSTEM; } set_error(COMMON_SUCCESS); return COMMON_SUCCESS; } ​ /** * @brief 锁定互斥锁 */ common_error_t common_mutex_lock(common_mutex_t mutex) { if (!g_common_state.modules[MODULE_THREAD]) { LOG_ERROR(COMMON_MODULE_NAME, "线程模块未初始化"); set_error(COMMON_ERROR_NOT_INIT); return COMMON_ERROR_NOT_INIT; } if (mutex == NULL) { LOG_ERROR(COMMON_MODULE_NAME, "互斥锁句柄不能为NULL"); set_error(COMMON_ERROR_PARAM); return COMMON_ERROR_PARAM; } thread_error_t err = thread_mutex_lock((thread_mutex_t)mutex); if (err != THREAD_SUCCESS) { LOG_ERROR(COMMON_MODULE_NAME, "锁定互斥锁失败: %s", thread_strerror(err)); set_error(COMMON_ERROR_SYSTEM); return COMMON_ERROR_SYSTEM; } set_error(COMMON_SUCCESS); return COMMON_SUCCESS; } ​ /** * @brief 尝试锁定互斥锁 */ common_error_t common_mutex_trylock(common_mutex_t mutex) { if (!g_common_state.modules[MODULE_THREAD]) { LOG_ERROR(COMMON_MODULE_NAME, "线程模块未初始化"); set_error(COMMON_ERROR_NOT_INIT); return COMMON_ERROR_NOT_INIT; } if (mutex == NULL) { LOG_ERROR(COMMON_MODULE_NAME, "互斥锁句柄不能为NULL"); set_error(COMMON_ERROR_PARAM); return COMMON_ERROR_PARAM; } thread_error_t err = thread_mutex_trylock((thread_mutex_t)mutex); if (err == THREAD_ERROR_TIMEOUT) { set_error(COMMON_ERROR_TIMEOUT); return COMMON_ERROR_TIMEOUT; } else if (err != THREAD_SUCCESS) { LOG_ERROR(COMMON_MODULE_NAME, "尝试锁定互斥锁失败: %s", thread_strerror(err)); set_error(COMMON_ERROR_SYSTEM); return COMMON_ERROR_SYSTEM; } set_error(COMMON_SUCCESS); return COMMON_SUCCESS; } ​ /** * @brief 解锁互斥锁 */ common_error_t common_mutex_unlock(common_mutex_t mutex) { if (!g_common_state.modules[MODULE_THREAD]) { LOG_ERROR(COMMON_MODULE_NAME, "线程模块未初始化"); set_error(COMMON_ERROR_NOT_INIT); return COMMON_ERROR_NOT_INIT; } if (mutex == NULL) { LOG_ERROR(COMMON_MODULE_NAME, "互斥锁句柄不能为NULL"); set_error(COMMON_ERROR_PARAM); return COMMON_ERROR_PARAM; } thread_error_t err = thread_mutex_unlock((thread_mutex_t)mutex); if (err != THREAD_SUCCESS) { LOG_ERROR(COMMON_MODULE_NAME, "解锁互斥锁失败: %s", thread_strerror(err)); set_error(COMMON_ERROR_SYSTEM); return COMMON_ERROR_SYSTEM; } set_error(COMMON_SUCCESS); return COMMON_SUCCESS; } ​ /* ==================== 条件变量接口实现 ==================== */ ​ /** * @brief 创建条件变量 */ common_cond_t common_cond_create(void) { if (!g_common_state.modules[MODULE_THREAD]) { LOG_ERROR(COMMON_MODULE_NAME, "线程模块未初始化"); set_error(COMMON_ERROR_NOT_INIT); return NULL; } thread_cond_t cond; thread_error_t err = thread_cond_create(&cond); if (err != THREAD_SUCCESS) { LOG_ERROR(COMMON_MODULE_NAME, "创建条件变量失败: %s", thread_strerror(err)); set_error(COMMON_ERROR_SYSTEM); return NULL; } set_error(COMMON_SUCCESS); return (common_cond_t)cond; } ​ /** * @brief 销毁条件变量 */ common_error_t common_cond_destroy(common_cond_t cond) { if (!g_common_state.modules[MODULE_THREAD]) { LOG_ERROR(COMMON_MODULE_NAME, "线程模块未初始化"); set_error(COMMON_ERROR_NOT_INIT); return COMMON_ERROR_NOT_INIT; } if (cond == NULL) { LOG_ERROR(COMMON_MODULE_NAME, "条件变量句柄不能为NULL"); set_error(COMMON_ERROR_PARAM); return COMMON_ERROR_PARAM; } thread_error_t err = thread_cond_destroy((thread_cond_t)cond); if (err != THREAD_SUCCESS) { LOG_ERROR(COMMON_MODULE_NAME, "销毁条件变量失败: %s", thread_strerror(err)); set_error(COMMON_ERROR_SYSTEM); return COMMON_ERROR_SYSTEM; } set_error(COMMON_SUCCESS); return COMMON_SUCCESS; } ​ /** * @brief 等待条件变量 */ common_error_t common_cond_wait(common_cond_t cond, common_mutex_t mutex) { if (!g_common_state.modules[MODULE_THREAD]) { LOG_ERROR(COMMON_MODULE_NAME, "线程模块未初始化"); set_error(COMMON_ERROR_NOT_INIT); return COMMON_ERROR_NOT_INIT; } if (cond == NULL || mutex == NULL) { LOG_ERROR(COMMON_MODULE_NAME, "条件变量或互斥锁句柄不能为NULL"); set_error(COMMON_ERROR_PARAM); return COMMON_ERROR_PARAM; } thread_error_t err = thread_cond_wait((thread_cond_t)cond, (thread_mutex_t)mutex); if (err != THREAD_SUCCESS) { LOG_ERROR(COMMON_MODULE_NAME, "等待条件变量失败: %s", thread_strerror(err)); set_error(COMMON_ERROR_SYSTEM); return COMMON_ERROR_SYSTEM; } set_error(COMMON_SUCCESS); return COMMON_SUCCESS; } ​ /** * @brief 带超时等待条件变量 */ common_error_t common_cond_timedwait(common_cond_t cond, common_mutex_t mutex, unsigned int timeout_ms) { if (!g_common_state.modules[MODULE_THREAD]) { LOG_ERROR(COMMON_MODULE_NAME, "线程模块未初始化"); set_error(COMMON_ERROR_NOT_INIT); return COMMON_ERROR_NOT_INIT; } if (cond == NULL || mutex == NULL) { LOG_ERROR(COMMON_MODULE_NAME, "条件变量或互斥锁句柄不能为NULL"); set_error(COMMON_ERROR_PARAM); return COMMON_ERROR_PARAM; } thread_error_t err = thread_cond_timedwait((thread_cond_t)cond, (thread_mutex_t)mutex, timeout_ms); if (err == THREAD_ERROR_TIMEOUT) { set_error(COMMON_ERROR_TIMEOUT); return COMMON_ERROR_TIMEOUT; } else if (err != THREAD_SUCCESS) { LOG_ERROR(COMMON_MODULE_NAME, "超时等待条件变量失败: %s", thread_strerror(err)); set_error(COMMON_ERROR_SYSTEM); return COMMON_ERROR_SYSTEM; } set_error(COMMON_SUCCESS); return COMMON_SUCCESS; } ​ /** * @brief 唤醒一个等待条件变量的线程 */ common_error_t common_cond_signal(common_cond_t cond) { if (!g_common_state.modules[MODULE_THREAD]) { LOG_ERROR(COMMON_MODULE_NAME, "线程模块未初始化"); set_error(COMMON_ERROR_NOT_INIT); return COMMON_ERROR_NOT_INIT; } if (cond == NULL) { LOG_ERROR(COMMON_MODULE_NAME, "条件变量句柄不能为NULL"); set_error(COMMON_ERROR_PARAM); return COMMON_ERROR_PARAM; } thread_error_t err = thread_cond_signal((thread_cond_t)cond); if (err != THREAD_SUCCESS) { LOG_ERROR(COMMON_MODULE_NAME, "唤醒条件变量失败: %s", thread_strerror(err)); set_error(COMMON_ERROR_SYSTEM); return COMMON_ERROR_SYSTEM; } set_error(COMMON_SUCCESS); return COMMON_SUCCESS; } ​ /** * @brief 唤醒所有等待条件变量的线程 */ common_error_t common_cond_broadcast(common_cond_t cond) { if (!g_common_state.modules[MODULE_THREAD]) { LOG_ERROR(COMMON_MODULE_NAME, "线程模块未初始化"); set_error(COMMON_ERROR_NOT_INIT); return COMMON_ERROR_NOT_INIT; } if (cond == NULL) { LOG_ERROR(COMMON_MODULE_NAME, "条件变量句柄不能为NULL"); set_error(COMMON_ERROR_PARAM); return COMMON_ERROR_PARAM; } thread_error_t err = thread_cond_broadcast((thread_cond_t)cond); if (err != THREAD_SUCCESS) { LOG_ERROR(COMMON_MODULE_NAME, "广播条件变量失败: %s", thread_strerror(err)); set_error(COMMON_ERROR_SYSTEM); return COMMON_ERROR_SYSTEM; } set_error(COMMON_SUCCESS); return COMMON_SUCCESS; } ​ /* ==================== 信号量接口实现 ==================== */ ​ /** * @brief 创建信号量 */ common_sem_t common_sem_create(unsigned int initial_value) { if (!g_common_state.modules[MODULE_THREAD]) { LOG_ERROR(COMMON_MODULE_NAME, "线程模块未初始化"); set_error(COMMON_ERROR_NOT_INIT); return NULL; } thread_sem_t sem; thread_error_t err = thread_sem_create(&sem, initial_value); if (err != THREAD_SUCCESS) { LOG_ERROR(COMMON_MODULE_NAME, "创建信号量失败: %s", thread_strerror(err)); set_error(COMMON_ERROR_SYSTEM); return NULL; } set_error(COMMON_SUCCESS); return (common_sem_t)sem; } ​ /** * @brief 销毁信号量 */ common_error_t common_sem_destroy(common_sem_t sem) { if (!g_common_state.modules[MODULE_THREAD]) { LOG_ERROR(COMMON_MODULE_NAME, "线程模块未初始化"); set_error(COMMON_ERROR_NOT_INIT); return COMMON_ERROR_NOT_INIT; } if (sem == NULL) { LOG_ERROR(COMMON_MODULE_NAME, "信号量句柄不能为NULL"); set_error(COMMON_ERROR_PARAM); return COMMON_ERROR_PARAM; } thread_error_t err = thread_sem_destroy((thread_sem_t)sem); if (err != THREAD_SUCCESS) { LOG_ERROR(COMMON_MODULE_NAME, "销毁信号量失败: %s", thread_strerror(err)); set_error(COMMON_ERROR_SYSTEM); return COMMON_ERROR_SYSTEM; } set_error(COMMON_SUCCESS); return COMMON_SUCCESS; } ​ /** * @brief 等待信号量 */ common_error_t common_sem_wait(common_sem_t sem) { if (!g_common_state.modules[MODULE_THREAD]) { LOG_ERROR(COMMON_MODULE_NAME, "线程模块未初始化"); set_error(COMMON_ERROR_NOT_INIT); return COMMON_ERROR_NOT_INIT; } if (sem == NULL) { LOG_ERROR(COMMON_MODULE_NAME, "信号量句柄不能为NULL"); set_error(COMMON_ERROR_PARAM); return COMMON_ERROR_PARAM; } thread_error_t err = thread_sem_wait((thread_sem_t)sem); if (err != THREAD_SUCCESS) { LOG_ERROR(COMMON_MODULE_NAME, "等待信号量失败: %s", thread_strerror(err)); set_error(COMMON_ERROR_SYSTEM); return COMMON_ERROR_SYSTEM; } set_error(COMMON_SUCCESS); return COMMON_SUCCESS; } ​ /** * @brief 尝试等待信号量 */ common_error_t common_sem_trywait(common_sem_t sem) { if (!g_common_state.modules[MODULE_THREAD]) { LOG_ERROR(COMMON_MODULE_NAME, "线程模块未初始化"); set_error(COMMON_ERROR_NOT_INIT); return COMMON_ERROR_NOT_INIT; } if (sem == NULL) { LOG_ERROR(COMMON_MODULE_NAME, "信号量句柄不能为NULL"); set_error(COMMON_ERROR_PARAM); return COMMON_ERROR_PARAM; } thread_error_t err = thread_sem_trywait((thread_sem_t)sem); if (err == THREAD_ERROR_TIMEOUT) { set_error(COMMON_ERROR_TIMEOUT); return COMMON_ERROR_TIMEOUT; } else if (err != THREAD_SUCCESS) { LOG_ERROR(COMMON_MODULE_NAME, "尝试等待信号量失败: %s", thread_strerror(err)); set_error(COMMON_ERROR_SYSTEM); return COMMON_ERROR_SYSTEM; } set_error(COMMON_SUCCESS); return COMMON_SUCCESS; } ​ /** * @brief 带超时等待信号量 */ common_error_t common_sem_timedwait(common_sem_t sem, unsigned int timeout_ms) { if (!g_common_state.modules[MODULE_THREAD]) { LOG_ERROR(COMMON_MODULE_NAME, "线程模块未初始化"); set_error(COMMON_ERROR_NOT_INIT); return COMMON_ERROR_NOT_INIT; } if (sem == NULL) { LOG_ERROR(COMMON_MODULE_NAME, "信号量句柄不能为NULL"); set_error(COMMON_ERROR_PARAM); return COMMON_ERROR_PARAM; } thread_error_t err = thread_sem_timedwait((thread_sem_t)sem, timeout_ms); if (err == THREAD_ERROR_TIMEOUT) { set_error(COMMON_ERROR_TIMEOUT); return COMMON_ERROR_TIMEOUT; } else if (err != THREAD_SUCCESS) { LOG_ERROR(COMMON_MODULE_NAME, "超时等待信号量失败: %s", thread_strerror(err)); set_error(COMMON_ERROR_SYSTEM); return COMMON_ERROR_SYSTEM; } set_error(COMMON_SUCCESS); return COMMON_SUCCESS; } ​ /** * @brief 释放信号量 */ common_error_t common_sem_post(common_sem_t sem) { if (!g_common_state.modules[MODULE_THREAD]) { LOG_ERROR(COMMON_MODULE_NAME, "线程模块未初始化"); set_error(COMMON_ERROR_NOT_INIT); return COMMON_ERROR_NOT_INIT; } if (sem == NULL) { LOG_ERROR(COMMON_MODULE_NAME, "信号量句柄不能为NULL"); set_error(COMMON_ERROR_PARAM); return COMMON_ERROR_PARAM; } thread_error_t err = thread_sem_post((thread_sem_t)sem); if (err != THREAD_SUCCESS) { LOG_ERROR(COMMON_MODULE_NAME, "释放信号量失败: %s", thread_strerror(err)); set_error(COMMON_ERROR_SYSTEM); return COMMON_ERROR_SYSTEM; } set_error(COMMON_SUCCESS); return COMMON_SUCCESS; } ​ /** * @brief 获取信号量当前值 */ common_error_t common_sem_getvalue(common_sem_t sem, int* value) { if (!g_common_state.modules[MODULE_THREAD]) { LOG_ERROR(COMMON_MODULE_NAME, "线程模块未初始化"); set_error(COMMON_ERROR_NOT_INIT); return COMMON_ERROR_NOT_INIT; } if (sem == NULL || value == NULL) { LOG_ERROR(COMMON_MODULE_NAME, "信号量句柄或输出参数不能为NULL"); set_error(COMMON_ERROR_PARAM); return COMMON_ERROR_PARAM; } thread_error_t err = thread_sem_getvalue((thread_sem_t)sem, value); if (err != THREAD_SUCCESS) { LOG_ERROR(COMMON_MODULE_NAME, "获取信号量值失败: %s", thread_strerror(err)); set_error(COMMON_ERROR_SYSTEM); return COMMON_ERROR_SYSTEM; } set_error(COMMON_SUCCESS); return COMMON_SUCCESS; } ​

对外测试test_out.c

/** * @file common_test.c * @brief common模块测试程序 */ ​ #include <stdio.h> #include <stdlib.h> #include <string.h> #include "common.h" ​ #define TEST_MODULE_NAME "COMMON_OUT_TEST" #define NUM_THREADS_3 3 #define NUM_THREADS_4 4 ​ /* 测试线程数据 */ static common_mutex_t g_test_mutex = NULL; static int g_shared_counter = 0; ​ /* ==================== 测试用例函数 ==================== */ ​ /** * @brief 基本功能测试 */ static bool test_basic_functionality(void) { LOG_INFO(TEST_MODULE_NAME, "测试基本功能..."); /* 测试内存分配 */ void* ptr = common_malloc(100); if (ptr == NULL) { LOG_ERROR(TEST_MODULE_NAME, "内存分配失败"); return false; } strcpy((char*)ptr, "Hello, Common Module!"); LOG_INFO(TEST_MODULE_NAME, "分配内存: %s", (char*)ptr); /* 测试重新分配 */ ptr = common_realloc(ptr, 200); if (ptr == NULL) { LOG_ERROR(TEST_MODULE_NAME, "内存重新分配失败"); return false; } strcat((char*)ptr, " Reallocated!"); LOG_INFO(TEST_MODULE_NAME, "重新分配内存: %s", (char*)ptr); /* 测试calloc */ int* array = (int*)common_calloc(10, sizeof(int)); if (array == NULL) { LOG_ERROR(TEST_MODULE_NAME, "calloc分配失败"); common_free(ptr); return false; } /* 验证内存被清零 */ for (int i = 0; i < 10; i++) { if (array[i] != 0) { LOG_ERROR(TEST_MODULE_NAME, "calloc内存未清零"); common_free(ptr); common_free(array); return false; } } common_free(ptr); common_free(array); LOG_INFO(TEST_MODULE_NAME, "基本功能测试通过"); return true; } ​ /** * @brief 测试线程函数 */ static void* test_thread_func(void* arg) { int thread_id = *(int*)arg; LOG_INFO(TEST_MODULE_NAME, "线程 %d 开始执行", thread_id); /* 模拟工作 */ common_sleep(100); LOG_INFO(TEST_MODULE_NAME, "线程 %d 执行完成", thread_id); /* 返回结果 */ int* result = (int*)common_malloc(sizeof(int)); if (result != NULL) { *result = thread_id * 10; } return result; } ​ /** * @brief 线程功能测试 */ static bool test_thread_functionality(void) { LOG_INFO(TEST_MODULE_NAME, "测试线程功能..."); /* 创建线程 */ int thread_id = 1; void* thread = common_thread_create(test_thread_func, &thread_id, "TestThread-1"); if (thread == NULL) { LOG_ERROR(TEST_MODULE_NAME, "创建线程失败"); return false; } /* 等待线程完成 */ void* retval = NULL; common_error_t err = common_thread_join(thread, &retval); if (err != COMMON_SUCCESS) { LOG_ERROR(TEST_MODULE_NAME, "等待线程失败: %s", common_strerror(err)); return false; } /* 检查返回值 */ if (retval != NULL) { int* result = (int*)retval; LOG_INFO(TEST_MODULE_NAME, "线程返回值: %d", *result); common_free(retval); } /* 测试带属性的线程 */ common_thread_attr_t attr = { .stack_size = 0, .detach_state = false, .priority = 0 }; thread = common_thread_create_ex(test_thread_func, &thread_id, "TestThread-2", &attr); if (thread == NULL) { LOG_ERROR(TEST_MODULE_NAME, "创建带属性线程失败"); return false; } common_thread_join(thread, NULL); LOG_INFO(TEST_MODULE_NAME, "线程功能测试通过"); return true; } ​ /** * @brief 互斥锁测试线程函数 */ static void* mutex_test_thread(void* arg) { int thread_id = *(int*)arg; for (int i = 0; i < 100; i++) { common_mutex_lock(g_test_mutex); g_shared_counter++; LOG_DEBUG(TEST_MODULE_NAME, "线程 %d: 计数器 = %d", thread_id, g_shared_counter); common_mutex_unlock(g_test_mutex); common_thread_yield(); } return NULL; } ​ /** * @brief 互斥锁功能测试 */ static bool test_mutex_functionality(void) { LOG_INFO(TEST_MODULE_NAME, "测试互斥锁功能..."); /* 创建互斥锁 */ g_test_mutex = common_mutex_create(); if (g_test_mutex == NULL) { LOG_ERROR(TEST_MODULE_NAME, "创建互斥锁失败"); return false; } /* 创建多个线程竞争访问共享资源 */ //const int NUM_THREADS = 3; int thread_ids[NUM_THREADS_3] = {1, 2, 3}; void* threads[NUM_THREADS_3]; g_shared_counter = 0; /* 创建线程 */ for (int i = 0; i < NUM_THREADS_3; i++) { char name[32]; snprintf(name, sizeof(name), "MutexTest-%d", thread_ids[i]); threads[i] = common_thread_create(mutex_test_thread, &thread_ids[i], name); if (threads[i] == NULL) { LOG_ERROR(TEST_MODULE_NAME, "创建互斥测试线程 %d 失败", thread_ids[i]); /* 清理已创建的线程 */ for (int j = 0; j < i; j++) { common_thread_join(threads[j], NULL); } common_mutex_destroy(g_test_mutex); return false; } } /* 等待所有线程完成 */ for (int i = 0; i < NUM_THREADS_3; i++) { common_thread_join(threads[i], NULL); } /* 验证计数器值 */ int expected = NUM_THREADS_3 * 100; if (g_shared_counter != expected) { LOG_ERROR(TEST_MODULE_NAME, "计数器值错误: 期望 %d, 实际 %d", expected, g_shared_counter); common_mutex_destroy(g_test_mutex); return false; } LOG_INFO(TEST_MODULE_NAME, "互斥锁测试通过,最终计数器: %d", g_shared_counter); /* 测试trylock */ common_error_t err = common_mutex_trylock(g_test_mutex); if (err != COMMON_SUCCESS) { LOG_ERROR(TEST_MODULE_NAME, "尝试锁定失败: %s", common_strerror(err)); common_mutex_destroy(g_test_mutex); return false; } common_mutex_unlock(g_test_mutex); /* 销毁互斥锁 */ common_mutex_destroy(g_test_mutex); g_test_mutex = NULL; return true; } ​ /** * @brief 条件变量生产者线程函数 */ static void* producer_func(void* arg) { common_mutex_t mutex = *(common_mutex_t*)arg; common_cond_t cond = *((common_cond_t*)arg + 1); common_sleep(50); /* 模拟工作 */ common_mutex_lock(mutex); int* data = (int*)((void**)arg + 2); *data = 42; bool* ready = (bool*)((void**)arg + 3); *ready = true; LOG_INFO(TEST_MODULE_NAME, "生产者: 数据准备就绪"); common_cond_signal(cond); common_mutex_unlock(mutex); return NULL; } ​ /** * @brief 条件变量消费者线程函数 */ static void* consumer_func(void* arg) { common_mutex_t mutex = *(common_mutex_t*)arg; common_cond_t cond = *((common_cond_t*)arg + 1); common_mutex_lock(mutex); int* data = (int*)((void**)arg + 2); bool* ready = (bool*)((void**)arg + 3); while (!*ready) { LOG_INFO(TEST_MODULE_NAME, "消费者: 等待数据..."); common_cond_wait(cond, mutex); } LOG_INFO(TEST_MODULE_NAME, "消费者: 接收到数据: %d", *data); if (*data != 42) { LOG_ERROR(TEST_MODULE_NAME, "数据错误: 期望 42, 实际 %d", *data); } common_mutex_unlock(mutex); return NULL; } ​ /** * @brief 条件变量功能测试 */ static bool test_condition_variable(void) { LOG_INFO(TEST_MODULE_NAME, "测试条件变量功能..."); common_mutex_t mutex = common_mutex_create(); common_cond_t cond = common_cond_create(); if (mutex == NULL || cond == NULL) { LOG_ERROR(TEST_MODULE_NAME, "创建同步对象失败"); if (mutex != NULL) common_mutex_destroy(mutex); if (cond != NULL) common_cond_destroy(cond); return false; } /* 准备共享数据 */ int shared_data = 0; bool ready = false; /* 打包参数 */ void* args[4]; args[0] = mutex; args[1] = cond; args[2] = &shared_data; args[3] = &ready; /* 创建线程 */ void* producer = common_thread_create(producer_func, args, "Producer"); void* consumer = common_thread_create(consumer_func, args, "Consumer"); if (producer == NULL || consumer == NULL) { LOG_ERROR(TEST_MODULE_NAME, "创建线程失败"); if (producer != NULL) common_thread_join(producer, NULL); if (consumer != NULL) common_thread_join(consumer, NULL); common_cond_destroy(cond); common_mutex_destroy(mutex); return false; } /* 等待线程完成 */ common_thread_join(producer, NULL); common_thread_join(consumer, NULL); /* 验证结果 */ if (shared_data != 42 || !ready) { LOG_ERROR(TEST_MODULE_NAME, "条件变量测试失败"); common_cond_destroy(cond); common_mutex_destroy(mutex); return false; } /* 清理 */ common_cond_destroy(cond); common_mutex_destroy(mutex); LOG_INFO(TEST_MODULE_NAME, "条件变量测试通过"); return true; } ​ /** * @brief 信号量测试线程函数 */ static void* semaphore_test_thread(void* arg) { common_sem_t sem = *(common_sem_t*)arg; int thread_id = *((int*)arg + 1); for (int i = 0; i < 10; i++) { common_sem_wait(sem); LOG_DEBUG(TEST_MODULE_NAME, "线程 %d: 获取信号量", thread_id); common_sleep(10); /* 模拟工作 */ common_sem_post(sem); common_sleep(5); } return NULL; } ​ /** * @brief 信号量功能测试 */ static bool test_semaphore_functionality(void) { LOG_INFO(TEST_MODULE_NAME, "测试信号量功能..."); /* 创建信号量 */ common_sem_t sem = common_sem_create(2); /* 允许两个线程同时访问 */ if (sem == NULL) { LOG_ERROR(TEST_MODULE_NAME, "创建信号量失败"); return false; } /* 测试获取当前值 */ int value = 0; common_error_t err = common_sem_getvalue(sem, &value); if (err != COMMON_SUCCESS || value != 2) { LOG_ERROR(TEST_MODULE_NAME, "信号量初始值错误"); common_sem_destroy(sem); return false; } /* 创建多个线程 */ //const int NUM_THREADS = 4; void* threads[NUM_THREADS_4]; for (int i = 0; i < NUM_THREADS_4; i++) { /* 准备参数 */ void* args[2]; args[0] = sem; args[1] = &i; char name[32]; snprintf(name, sizeof(name), "SemTest-%d", i); threads[i] = common_thread_create(semaphore_test_thread, args, name); if (threads[i] == NULL) { LOG_ERROR(TEST_MODULE_NAME, "创建信号量测试线程 %d 失败", i); /* 清理已创建的线程 */ for (int j = 0; j < i; j++) { common_thread_join(threads[j], NULL); } common_sem_destroy(sem); return false; } } /* 等待所有线程完成 */ for (int i = 0; i < NUM_THREADS_4; i++) { common_thread_join(threads[i], NULL); } /* 清理 */ common_sem_destroy(sem); LOG_INFO(TEST_MODULE_NAME, "信号量测试通过"); return true; } ​ /** * @brief 日志功能测试 */ static bool test_log_functionality(void) { LOG_INFO(TEST_MODULE_NAME, "测试日志功能..."); /* 测试各种日志级别 */ LOG_DEBUG(TEST_MODULE_NAME, "这是一条调试信息"); LOG_INFO(TEST_MODULE_NAME, "这是一条信息"); LOG_WARN(TEST_MODULE_NAME, "这是一条警告"); LOG_ERROR(TEST_MODULE_NAME, "这是一条错误"); LOG_FATAL(TEST_MODULE_NAME, "这是一条致命错误"); /* 测试日志级别设置 */ log_level_t old_level = common_log_get_level(); /* 设置为只显示错误以上级别 */ common_log_set_level(LOG_LEVEL_ERROR); LOG_INFO(TEST_MODULE_NAME, "这条信息不应该显示"); /* 恢复原级别 */ common_log_set_level(old_level); /* 测试控制台输出开关 */ common_log_set_console_output(false); LOG_INFO(TEST_MODULE_NAME, "这条信息在控制台不可见"); common_log_set_console_output(true); LOG_INFO(TEST_MODULE_NAME, "日志功能测试通过"); return true; } ​ /** * @brief 内存泄漏检测测试 */ static bool test_memory_leak_detection(void) { LOG_INFO(TEST_MODULE_NAME, "测试内存泄漏检测..."); /* 获取初始泄漏数量 */ size_t initial_leaks = common_check_memory_leaks(); LOG_INFO(TEST_MODULE_NAME, "初始内存泄漏: %zu", initial_leaks); /* 故意创建一些泄漏 */ void* leak1 = common_malloc(100); void* leak2 = common_malloc(200); /* 检查泄漏数量 */ size_t current_leaks = common_check_memory_leaks(); LOG_INFO(TEST_MODULE_NAME, "创建泄漏后内存泄漏: %zu", current_leaks); if (current_leaks <= initial_leaks) { LOG_ERROR(TEST_MODULE_NAME, "内存泄漏检测失败"); common_free(leak1); common_free(leak2); return false; } /* 修复泄漏 */ common_free(leak1); common_free(leak2); /* 再次检查 */ size_t final_leaks = common_check_memory_leaks(); LOG_INFO(TEST_MODULE_NAME, "修复泄漏后内存泄漏: %zu", final_leaks); if (final_leaks > initial_leaks) { LOG_ERROR(TEST_MODULE_NAME, "内存泄漏未完全修复"); return false; } LOG_INFO(TEST_MODULE_NAME, "内存泄漏检测测试通过"); return true; } ​ /* ==================== 主测试程序 ==================== */ ​ /** * @brief 注册并运行所有测试 */ static int run_all_tests(void) { struct { const char* name; bool (*func)(void); } tests[] = { {"基本功能测试", test_basic_functionality}, {"线程功能测试", test_thread_functionality}, {"互斥锁测试", test_mutex_functionality}, {"条件变量测试", test_condition_variable}, {"信号量测试", test_semaphore_functionality}, {"日志功能测试", test_log_functionality}, {"内存泄漏检测", test_memory_leak_detection}, }; int passed = 0; int failed = 0; printf("\n========== 开始运行 Common 模块测试 ==========\n"); printf("测试用例总数: %zu\n", sizeof(tests)/sizeof(tests[0])); printf("---------------------------------------------\n"); for (size_t i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { printf("运行测试 [%02zu/%02zu]: %-30s ", i + 1, sizeof(tests)/sizeof(tests[0]), tests[i].name); fflush(stdout); if (tests[i].func()) { printf("[PASS]\n"); passed++; } else { printf("[FAIL]\n"); failed++; } } printf("---------------------------------------------\n"); printf("测试完成:\n"); printf(" 通过: %d\n", passed); printf(" 失败: %d\n", failed); printf("========== 测试运行结束 ==========\n\n"); return failed; } ​ /** * @brief 主函数 */ int main(void) { printf("=======================================\n"); printf(" Common 模块测试程序\n"); printf("=======================================\n\n"); /* 初始化所有模块 */ common_error_t err = common_init_all(); if (err != COMMON_SUCCESS) { printf("初始化失败: %s\n", common_strerror(err)); return 1; } printf("✅ 所有模块初始化成功\n"); /* 运行所有测试 */ int failed_tests = run_all_tests(); /* 打印最终内存统计 */ printf("\n最终内存统计:\n"); common_print_memory_stats(); size_t leaks = common_check_memory_leaks(); if (leaks > 0) { printf("⚠️ 发现 %zu 处内存泄漏!\n", leaks); } else { printf("✅ 无内存泄漏\n"); } /* 销毁所有模块 */ common_destroy_all(); printf("\n=======================================\n"); printf(" 测试程序运行完成\n"); printf("=======================================\n"); return (failed_tests > 0) ? 1 : 0; } ​

对外测试log

tang@ubuntu:~/Desktop/project/2025_work/tools_file$ ./build/test_common ======================================= Common 模块测试程序 ======================================= ​ [12:07:02] INFO [LOG_BASE] Log module initialized [12:07:02] INFO [COMMON] 日志模块初始化成功 [12:07:02] INFO [COMMON] 初始化内存模块... [12:07:02] INFO [MEMORY] 内存追踪模块初始化成功,最大追踪数量: 2048 [12:07:02] INFO [COMMON] 内存模块初始化成功 [12:07:02] INFO [COMMON] 初始化线程模块... [12:07:02] INFO [THREAD] 线程模块初始化成功 [12:07:02] INFO [COMMON] 线程模块初始化成功 [12:07:02] INFO [COMMON] 所有模块初始化完成 ✅ 所有模块初始化成功 ​ ========== 开始运行 Common 模块测试 ========== 测试用例总数: 7 --------------------------------------------- 运行测试 [01/07]: 基本功能测试 [12:07:02] INFO [COMMON_OUT_TEST] 测试基本功能... [12:07:02] INFO [COMMON_OUT_TEST] 分配内存: Hello, Common Module! [12:07:02] INFO [COMMON_OUT_TEST] 重新分配内存: Hello, Common Module! Reallocated! [12:07:02] INFO [COMMON_OUT_TEST] 基本功能测试通过 [PASS] 运行测试 [02/07]: 线程功能测试 [12:07:02] INFO [COMMON_OUT_TEST] 测试线程功能... [12:07:02] INFO [THREAD] 成功创建线程: TestThread-1 (句柄: 0x55d403e9ba10, ID: 140658506032896) [12:07:02] INFO [THREAD] 线程 [TestThread-1] 开始执行, 线程ID: 140658506032896 [12:07:02] INFO [COMMON_OUT_TEST] 线程 1 开始执行 [12:07:02] INFO [COMMON_OUT_TEST] 线程 1 执行完成 [12:07:02] INFO [THREAD] 线程 [TestThread-1] 执行结束, 返回值: 0x7fed94000b60 [12:07:02] INFO [THREAD] 线程 [TestThread-1] 等待结束,返回值: 0x7fed94000b60 [12:07:02] INFO [COMMON_OUT_TEST] 线程返回值: 10 [12:07:02] INFO [THREAD] 成功创建线程: TestThread-2 (句柄: 0x55d403e9bb90, ID: 140658506032896) [12:07:02] INFO [THREAD] 线程 [TestThread-2] 开始执行, 线程ID: 140658506032896 [12:07:02] INFO [COMMON_OUT_TEST] 线程 1 开始执行 [12:07:02] INFO [COMMON_OUT_TEST] 线程 1 执行完成 [12:07:02] INFO [THREAD] 线程 [TestThread-2] 执行结束, 返回值: 0x7fed94000b80 [12:07:02] INFO [THREAD] 线程 [TestThread-2] 等待结束,返回值: 0x7fed94000b80 [12:07:02] INFO [COMMON_OUT_TEST] 线程功能测试通过 [PASS] 运行测试 [03/07]: 互斥锁测试 [12:07:02] INFO [COMMON_OUT_TEST] 测试互斥锁功能... [12:07:02] INFO [THREAD] 成功创建线程: MutexTest-1 (句柄: 0x55d403e9bc40, ID: 140658506032896) [12:07:02] INFO [THREAD] 线程 [MutexTest-1] 开始执行, 线程ID: 140658506032896 [12:07:02] INFO [THREAD] 成功创建线程: MutexTest-2 (句柄: 0x55d403e9bca0, ID: 140658497640192) [12:07:02] INFO [THREAD] 线程 [MutexTest-2] 开始执行, 线程ID: 140658497640192 [12:07:02] INFO [THREAD] 线程 [MutexTest-1] 执行结束, 返回值: (nil) [12:07:02] INFO [THREAD] 成功创建线程: MutexTest-3 (句柄: 0x55d403e9be20, ID: 140658489247488) [12:07:02] INFO [THREAD] 线程 [MutexTest-3] 开始执行, 线程ID: 140658489247488 [12:07:02] INFO [THREAD] 线程 [MutexTest-1] 等待结束,返回值: (nil) [12:07:02] INFO [THREAD] 线程 [MutexTest-2] 执行结束, 返回值: (nil) [12:07:02] INFO [THREAD] 线程 [MutexTest-2] 等待结束,返回值: (nil) [12:07:02] INFO [THREAD] 线程 [MutexTest-3] 执行结束, 返回值: (nil) [12:07:02] INFO [THREAD] 线程 [MutexTest-3] 等待结束,返回值: (nil) [12:07:02] INFO [COMMON_OUT_TEST] 互斥锁测试通过,最终计数器: 300 [PASS] 运行测试 [04/07]: 条件变量测试 [12:07:02] INFO [COMMON_OUT_TEST] 测试条件变量功能... [12:07:02] INFO [THREAD] 成功创建线程: Producer (句柄: 0x55d403e9c000, ID: 140658489247488) [12:07:02] INFO [THREAD] 线程 [Producer] 开始执行, 线程ID: 140658489247488 [12:07:02] INFO [THREAD] 成功创建线程: Consumer (句柄: 0x55d403e9c060, ID: 140658497640192) [12:07:02] INFO [THREAD] 线程 [Consumer] 开始执行, 线程ID: 140658497640192 [12:07:02] INFO [COMMON_OUT_TEST] 消费者: 等待数据... [12:07:02] INFO [COMMON_OUT_TEST] 生产者: 数据准备就绪 [12:07:02] INFO [THREAD] 线程 [Producer] 执行结束, 返回值: (nil) [12:07:02] INFO [COMMON_OUT_TEST] 消费者: 接收到数据: 42 [12:07:02] INFO [THREAD] 线程 [Consumer] 执行结束, 返回值: (nil) [12:07:02] INFO [THREAD] 线程 [Producer] 等待结束,返回值: (nil) [12:07:02] INFO [THREAD] 线程 [Consumer] 等待结束,返回值: (nil) [12:07:02] ERROR [COMMON_OUT_TEST] 条件变量测试失败 [FAIL] 运行测试 [05/07]: 信号量测试 [12:07:02] INFO [COMMON_OUT_TEST] 测试信号量功能... [12:07:02] INFO [THREAD] 成功创建线程: SemTest-0 (句柄: 0x55d403e9bfa0, ID: 140658497640192) [12:07:02] INFO [THREAD] 线程 [SemTest-0] 开始执行, 线程ID: 140658497640192 [12:07:02] INFO [THREAD] 成功创建线程: SemTest-1 (句柄: 0x55d403e9c0c0, ID: 140658489247488) [12:07:02] INFO [THREAD] 线程 [SemTest-1] 开始执行, 线程ID: 140658489247488 [12:07:02] INFO [THREAD] 成功创建线程: SemTest-2 (句柄: 0x55d403e9c120, ID: 140658506032896) [12:07:02] INFO [THREAD] 线程 [SemTest-2] 开始执行, 线程ID: 140658506032896 [12:07:02] INFO [THREAD] 成功创建线程: SemTest-3 (句柄: 0x55d403e9c180, ID: 140658480854784) [12:07:02] INFO [THREAD] 线程 [SemTest-3] 开始执行, 线程ID: 140658480854784 [12:07:02] INFO [THREAD] 线程 [SemTest-1] 执行结束, 返回值: (nil) [12:07:02] INFO [THREAD] 线程 [SemTest-0] 执行结束, 返回值: (nil) [12:07:02] INFO [THREAD] 线程 [SemTest-0] 等待结束,返回值: (nil) [12:07:02] INFO [THREAD] 线程 [SemTest-1] 等待结束,返回值: (nil) [12:07:02] INFO [THREAD] 线程 [SemTest-2] 执行结束, 返回值: (nil) [12:07:02] INFO [THREAD] 线程 [SemTest-3] 执行结束, 返回值: (nil) [12:07:02] INFO [THREAD] 线程 [SemTest-2] 等待结束,返回值: (nil) [12:07:02] INFO [THREAD] 线程 [SemTest-3] 等待结束,返回值: (nil) [12:07:02] INFO [COMMON_OUT_TEST] 信号量测试通过 [PASS] 运行测试 [06/07]: 日志功能测试 [12:07:02] INFO [COMMON_OUT_TEST] 测试日志功能... [12:07:02] INFO [COMMON_OUT_TEST] 这是一条信息 [12:07:02] WARN [COMMON_OUT_TEST] 这是一条警告 [12:07:02] ERROR [COMMON_OUT_TEST] 这是一条错误 [12:07:02] FATAL [COMMON_OUT_TEST] 这是一条致命错误 [12:07:02] INFO [COMMON_OUT_TEST] 日志功能测试通过 [PASS] 运行测试 [07/07]: 内存泄漏检测 [12:07:02] INFO [COMMON_OUT_TEST] 测试内存泄漏检测... [12:07:02] INFO [COMMON_OUT_TEST] 初始内存泄漏: 12 [12:07:02] INFO [COMMON_OUT_TEST] 创建泄漏后内存泄漏: 14 [12:07:02] INFO [COMMON_OUT_TEST] 修复泄漏后内存泄漏: 12 [12:07:02] INFO [COMMON_OUT_TEST] 内存泄漏检测测试通过 [PASS] --------------------------------------------- 测试完成: 通过: 6 失败: 1 ========== 测试运行结束 ========== ​ ​ 最终内存统计: ​ ========== 内存统计信息 ========== 当前已分配内存: 884 bytes 峰值内存使用: 1184 bytes 总分配次数: 21 总释放次数: 9 释放失败次数: 0 当前追踪数量: 12/2048 内存泄漏数量: 12 =================================== ⚠️ 发现 12 处内存泄漏! [12:07:02] INFO [COMMON] 开始销毁所有模块... [12:07:02] INFO [COMMON] 销毁线程模块... [12:07:02] INFO [THREAD] 开始销毁线程模块 [12:07:03] INFO [THREAD] 线程模块销毁完成 [12:07:03] INFO [COMMON] 线程模块销毁完成 [12:07:03] INFO [COMMON] 销毁内存模块... [12:07:03] ERROR [MEMORY] 发现 1 处内存泄漏 ​ ========== 内存泄漏详情 ========== 泄漏 #1: 地址: 0x7fed94000b80 大小: 4 bytes 位置: src/memory.c:404 函数: memory_malloc() 时间: 2025-12-15 12:07:02 ​ 总计: 1 处泄漏,共 4 bytes ================================== ​ ========== 内存统计信息 ========== 当前已分配内存: 4 bytes 峰值内存使用: 1184 bytes 总分配次数: 21 总释放次数: 20 释放失败次数: 0 当前追踪数量: 1/2048 内存泄漏数量: 1 =================================== [12:07:03] INFO [MEMORY] 内存追踪模块已销毁 [12:07:03] INFO [COMMON] 内存模块销毁完成 [12:07:03] INFO [COMMON] 销毁日志模块... [12:07:03] INFO [LOG_BASE] Log module destroyed ​ ======================================= 测试程序运行完成 =======================================

第二部分 内部封装

log.h

#ifndef LOG_H #define LOG_H ​ #include <stdbool.h> #include <stddef.h> ​ typedef enum { LOG_BASE_LEVEL_DEBUG = 0, LOG_BASE_LEVEL_INFO, LOG_BASE_LEVEL_WARN, LOG_BASE_LEVEL_ERROR, LOG_BASE_LEVEL_FATAL } log_base_level_t; ​ /** * @brief 初始化日志模块 * @param buffer_size 日志缓冲区大小(字节) * @return true 初始化成功 * @return false 初始化失败 */ bool log_init(size_t buffer_size); ​ /** * @brief 销毁日志模块 */ void log_destroy(void); ​ /** * @brief 记录日志 * @param level 日志级别 * @param module 模块名称 * @param format 格式字符串 * @param ... 可变参数 */ void base_log(log_base_level_t level, const char* module, const char* format, ...); ​ /** * @brief 设置日志级别 * @param level 要设置的日志级别 */ void log_set_level(log_base_level_t level); ​ /** * @brief 获取当前日志级别 * @return log_base_level_t 当前日志级别 */ log_base_level_t log_get_level(void); ​ /** * @brief 设置控制台输出 * @param enable true启用控制台输出,false禁用 */ void log_set_console_output(bool enable); ​ #endif /* LOG_H */ ​

memory.h

/** * @file memory.h * @brief 内存追踪模块头文件 * * 本模块提供内存分配追踪功能,用于检测内存泄漏、重复释放和无效释放等问题。 * 替换标准的内存分配函数,保持接口兼容。 */ ​ #ifndef MEMORY_H #define MEMORY_H ​ #include <stddef.h> #include <stdbool.h> ​ #ifdef __cplusplus extern "C" { #endif ​ /** * @brief 初始化内存追踪模块 * * 必须在调用任何内存分配函数之前调用此函数。 * 如果初始化失败,内存分配将回退到标准库函数。 * * @return true 初始化成功 * @return false 初始化失败 */ bool memory_init(void); ​ /** * @brief 销毁内存追踪模块 * * 释放所有资源,并打印内存泄漏报告。 * 程序退出前应调用此函数。 */ void memory_destroy(void); ​ /** * @brief 启用或禁用内存追踪 * * 可以在运行时动态启用或禁用内存追踪。 * 禁用后,内存分配将使用标准库函数。 * * @param enable true启用追踪,false禁用追踪 */ void memory_set_tracking(bool enable); ​ /** * @brief 获取当前是否启用了内存追踪 * * @return true 已启用 * @return false 未启用 */ bool memory_is_tracking_enabled(void); ​ /** * @brief 分配内存(替换标准malloc) * * 分配指定大小的内存块,并记录分配信息。 * 如果内存追踪未启用,则直接调用标准malloc。 * * @param size 要分配的字节数 * @return void* 指向分配内存的指针,失败返回NULL */ void* memory_malloc(size_t size); ​ /** * @brief 分配并清零内存(替换标准calloc) * * 分配指定数量和大小的内存块,并初始化为0。 * 如果内存追踪未启用,则直接调用标准calloc。 * * @param nmemb 元素数量 * @param size 每个元素的大小 * @return void* 指向分配内存的指针,失败返回NULL */ void* memory_calloc(size_t nmemb, size_t size); ​ /** * @brief 重新分配内存(替换标准realloc) * * 调整已分配内存块的大小。 * 如果内存追踪未启用,则直接调用标准realloc。 * * @param ptr 要调整的内存指针 * @param size 新的字节数 * @return void* 指向重新分配内存的指针,失败返回NULL */ void* memory_realloc(void* ptr, size_t size); ​ /** * @brief 释放内存(替换标准free) * * 释放先前分配的内存块,并检查是否重复释放。 * 如果内存追踪未启用,则直接调用标准free。 * * @param ptr 要释放的内存指针 */ void memory_free(void* ptr); ​ /** * @brief 检查内存泄漏 * * 检查当前是否有未释放的内存块。 * * @return size_t 泄漏的内存块数量 */ size_t memory_check_leaks(void); ​ /** * @brief 打印内存统计信息 * * 打印当前内存使用情况的统计信息。 */ void memory_print_stats(void); ​ /** * @brief 打印详细泄漏信息 * * 打印所有未释放内存块的详细信息。 */ void memory_print_leak_details(void); ​ /** * @brief 获取当前已分配内存总量 * * @return size_t 当前分配的字节数 */ size_t memory_get_current_total(void); ​ /** * @brief 获取峰值内存使用量 * * @return size_t 峰值分配的字节数 */ size_t memory_get_peak_total(void); ​ /** * @brief 获取总分配次数 * * @return size_t 分配调用次数 */ size_t memory_get_allocation_count(void); ​ /** * @brief 获取总释放次数 * * @return size_t 释放调用次数 */ size_t memory_get_free_count(void); ​ /** * @brief 获取释放失败次数 * * 包括重复释放、无效指针等。 * * @return size_t 释放失败次数 */ size_t memory_get_failed_free_count(void); ​ #ifdef __cplusplus } #endif ​ #endif /* MEMORY_H */ ​

test_common.h

/** * @file test_common.h * @brief 测试辅助函数头文件 */ ​ #ifndef TEST_COMMON_H #define TEST_COMMON_H ​ #include <stdbool.h> #include <stddef.h> ​ #ifdef __cplusplus extern "C" { #endif ​ #define TEST_MODULE_NAME "TEST" ​ /** * @brief 断言宏 */ #define TEST_ASSERT(condition, message) \ do { \ if (!(condition)) { \ return false; \ } \ } while(0) ​ /** * @brief 断言两个值相等 */ #define TEST_ASSERT_EQ(expected, actual, message) \ TEST_ASSERT((expected) == (actual), message) ​ /** * @brief 断言指针不为NULL */ #define TEST_ASSERT_NOT_NULL(ptr, message) \ TEST_ASSERT((ptr) != NULL, message) ​ /** * @brief 断言指针为NULL */ #define TEST_ASSERT_NULL(ptr, message) \ TEST_ASSERT((ptr) == NULL, message) ​ /** * @brief 注册测试用例 */ void test_register(const char* name, bool (*func)(void)); ​ /** * @brief 运行所有测试 */ int test_run_all(void); ​ /** * @brief 打印测试摘要 */ void test_print_summary(void); ​ /** * @brief 注册所有内存测试用例 */ void test_memory_register_all(void); ​ /** * @brief 注册所有线程测试用例 */ void test_thread_register_all(void); ​ #ifdef __cplusplus } #endif ​ #endif /* TEST_COMMON_H */ ​

thread_linux.h

/** * @file thread_linux.h * @brief Linux 线程通用接口封装 * * 基于标准 pthread 库封装线程接口,集成日志和内存追踪功能。 * 提供线程创建、销毁、同步等通用操作。 */ ​ #ifndef THREAD_LINUX_H #define THREAD_LINUX_H ​ #include <stdbool.h> #include <stddef.h> ​ #ifdef __cplusplus extern "C" { #endif ​ /* ==================== 基本类型定义 ==================== */ ​ /** @brief 线程句柄(不透明指针) */ typedef void* thread_handle_t; ​ /** @brief 互斥锁句柄 */ typedef void* thread_mutex_t; ​ /** @brief 条件变量句柄 */ typedef void* thread_cond_t; ​ /** @brief 信号量句柄 */ typedef void* thread_sem_t; ​ /** @brief 线程属性句柄 */ typedef void* thread_attr_t; ​ /** @brief 线程函数指针类型 */ typedef void* (*thread_func_t)(void* arg); ​ /* ==================== 线程状态枚举 ==================== */ ​ /** * @brief 线程状态枚举 */ typedef enum { THREAD_STATE_CREATED = 0, /**< 线程已创建但未启动 */ THREAD_STATE_RUNNING, /**< 线程正在运行 */ THREAD_STATE_WAITING, /**< 线程正在等待(阻塞) */ THREAD_STATE_TERMINATED, /**< 线程已终止 */ THREAD_STATE_DETACHED /**< 线程已分离 */ } thread_state_t; ​ /* ==================== 错误码枚举 ==================== */ ​ /** * @brief 线程错误码 */ typedef enum { THREAD_SUCCESS = 0, /**< 操作成功 */ THREAD_ERROR_INIT, /**< 初始化失败 */ THREAD_ERROR_MEMORY, /**< 内存分配失败 */ THREAD_ERROR_CREATE, /**< 创建线程失败 */ THREAD_ERROR_PARAM, /**< 参数错误 */ THREAD_ERROR_NOT_FOUND, /**< 未找到线程 */ THREAD_ERROR_DEADLOCK, /**< 死锁风险 */ THREAD_ERROR_TIMEOUT, /**< 操作超时 */ THREAD_ERROR_SYSTEM /**< 系统调用失败 */ } thread_error_t; ​ /* ==================== 初始化与销毁 ==================== */ ​ /** * @brief 初始化线程模块 * * 必须在调用任何线程函数之前调用此函数。 * * @return thread_error_t 错误码,THREAD_SUCCESS表示成功 */ thread_error_t thread_module_init(void); ​ /** * @brief 销毁线程模块 * * 释放所有资源,应在程序退出前调用。 * 会检查是否有未销毁的线程和同步对象。 */ void thread_module_destroy(void); ​ /* ==================== 线程管理接口 ==================== */ ​ /** * @brief 创建线程 * * @param func 线程函数 * @param arg 传递给线程函数的参数 * @param name 线程名称(可选),NULL表示自动生成 * @param handle 输出参数,接收线程句柄 * @return thread_error_t 错误码 */ thread_error_t thread_create(thread_func_t func, void* arg, const char* name, thread_handle_t* handle); ​ /** * @brief 创建带属性的线程 * * @param func 线程函数 * @param arg 传递给线程函数的参数 * @param name 线程名称 * @param stack_size 栈大小(字节),0表示默认值 * @param detach_state 是否分离(true:分离, false:可连接) * @param handle 输出参数,接收线程句柄 * @return thread_error_t 错误码 */ thread_error_t thread_create_ex(thread_func_t func, void* arg, const char* name, size_t stack_size, bool detach_state, thread_handle_t* handle); ​ /** * @brief 等待线程结束 * * 阻塞当前线程,直到指定线程结束。 * * @param handle 线程句柄 * @param retval 输出参数,接收线程返回值,NULL表示不接收 * @return thread_error_t 错误码 */ thread_error_t thread_join(thread_handle_t handle, void** retval); ​ /** * @brief 分离线程 * * 将线程设置为分离状态,线程结束后自动回收资源。 * * @param handle 线程句柄 * @return thread_error_t 错误码 */ thread_error_t thread_detach(thread_handle_t handle); ​ /** * @brief 取消线程 * * 请求取消指定线程的执行。 * * @param handle 线程句柄 * @return thread_error_t 错误码 */ thread_error_t thread_cancel(thread_handle_t handle); ​ /** * @brief 获取当前线程句柄 * * @return thread_handle_t 当前线程句柄 */ thread_handle_t thread_self(void); ​ /** * @brief 获取线程状态 * * @param handle 线程句柄 * @param state 输出参数,接收线程状态 * @return thread_error_t 错误码 */ thread_error_t thread_get_state(thread_handle_t handle, thread_state_t* state); ​ /** * @brief 获取线程名称 * * @param handle 线程句柄 * @param name 输出缓冲区 * @param size 缓冲区大小 * @return thread_error_t 错误码 */ thread_error_t thread_get_name(thread_handle_t handle, char* name, size_t size); ​ /** * @brief 设置线程名称 * * @param handle 线程句柄 * @param name 新的线程名称 * @return thread_error_t 错误码 */ thread_error_t thread_set_name(thread_handle_t handle, const char* name); ​ /** * @brief 销毁线程句柄 * * 释放线程资源,但不终止线程本身。 * 线程必须已经终止或被分离。 * * @param handle 线程句柄 * @return thread_error_t 错误码 */ thread_error_t thread_destroy(thread_handle_t handle); ​ /* ==================== 线程控制接口 ==================== */ ​ /** * @brief 让出CPU * * 当前线程主动放弃CPU,让其他线程运行。 */ void thread_yield(void); ​ /** * @brief 睡眠指定毫秒数 * * @param milliseconds 睡眠的毫秒数 */ void thread_sleep(unsigned int milliseconds); ​ /** * @brief 获取错误码描述 * * @param error 错误码 * @return const char* 错误描述字符串 */ const char* thread_strerror(thread_error_t error); ​ /** * @brief 等待信号量(P操作) * * 如果信号量值大于0,则减1并立即返回。 * 否则阻塞直到信号量值大于0。 * * @param sem 信号量句柄 * @return thread_error_t 错误码 */ thread_error_t thread_sem_wait(thread_sem_t sem); ​ /** * @brief 创建互斥锁 * * @param mutex 输出参数,接收互斥锁句柄 * @return thread_error_t 错误码 */ thread_error_t thread_mutex_create(thread_mutex_t* mutex); ​ /** * @brief 销毁互斥锁 * * @param mutex 互斥锁句柄 * @return thread_error_t 错误码 */ thread_error_t thread_mutex_destroy(thread_mutex_t mutex); ​ /** * @brief 锁定互斥锁 * * @param mutex 互斥锁句柄 * @return thread_error_t 错误码 */ thread_error_t thread_mutex_lock(thread_mutex_t mutex); ​ /** * @brief 解锁互斥锁 * * @param mutex 互斥锁句柄 * @return thread_error_t 错误码 */ thread_error_t thread_mutex_unlock(thread_mutex_t mutex); ​ /** * @brief 尝试锁定互斥锁 * * @param mutex 互斥锁句柄 * @return thread_error_t 成功返回THREAD_SUCCESS,被锁定返回THREAD_ERROR_TIMEOUT */ thread_error_t thread_mutex_trylock(thread_mutex_t mutex); ​ /* ==================== 条件变量接口实现 ==================== */ ​ /** * @brief 创建条件变量 * * @param cond 输出参数,接收条件变量句柄 * @return thread_error_t 错误码 */ thread_error_t thread_cond_create(thread_cond_t* cond); ​ /** * @brief 销毁条件变量 * * @param cond 条件变量句柄 * @return thread_error_t 错误码 */ thread_error_t thread_cond_destroy(thread_cond_t cond); ​ /** * @brief 等待条件变量 * * @param cond 条件变量句柄 * @param mutex 关联的互斥锁句柄 * @return thread_error_t 错误码 */ thread_error_t thread_cond_wait(thread_cond_t cond, thread_mutex_t mutex); ​ /** * @brief 带超时的等待条件变量 * * @param cond 条件变量句柄 * @param mutex 关联的互斥锁句柄 * @param timeout_ms 超时时间(毫秒) * @return thread_error_t 超时返回THREAD_ERROR_TIMEOUT */ thread_error_t thread_cond_timedwait(thread_cond_t cond, thread_mutex_t mutex, unsigned int timeout_ms); ​ /** * @brief 唤醒一个等待条件变量的线程 * * @param cond 条件变量句柄 * @return thread_error_t 错误码 */ thread_error_t thread_cond_signal(thread_cond_t cond); ​ /** * @brief 唤醒所有等待条件变量的线程 * * @param cond 条件变量句柄 * @return thread_error_t 错误码 */ thread_error_t thread_cond_broadcast(thread_cond_t cond); ​ /* ==================== 信号量接口实现 ==================== */ ​ /** * @brief 创建信号量 * * @param sem 输出参数,接收信号量句柄 * @param initial_value 初始值 * @return thread_error_t 错误码 */ thread_error_t thread_sem_create(thread_sem_t* sem, unsigned int initial_value); ​ /** * @brief 销毁信号量 * * @param sem 信号量句柄 * @return thread_error_t 错误码 */ thread_error_t thread_sem_destroy(thread_sem_t sem); ​ /** * @brief 等待信号量(P操作) * * @param sem 信号量句柄 * @return thread_error_t 错误码 */ thread_error_t thread_sem_wait(thread_sem_t sem); ​ /** * @brief 尝试等待信号量 * * @param sem 信号量句柄 * @return thread_error_t 信号量为0返回THREAD_ERROR_TIMEOUT */ thread_error_t thread_sem_trywait(thread_sem_t sem); ​ /** * @brief 带超时的等待信号量 * * @param sem 信号量句柄 * @param timeout_ms 超时时间(毫秒) * @return thread_error_t 超时返回THREAD_ERROR_TIMEOUT */ thread_error_t thread_sem_timedwait(thread_sem_t sem, unsigned int timeout_ms); ​ /** * @brief 释放信号量(V操作) * * 信号量值加1,唤醒一个等待的线程。 * * @param sem 信号量句柄 * @return thread_error_t 错误码 */ thread_error_t thread_sem_post(thread_sem_t sem); ​ /** * @brief 获取信号量当前值 * * @param sem 信号量句柄 * @param value 输出参数,接收信号量值 * @return thread_error_t 错误码 */ thread_error_t thread_sem_getvalue(thread_sem_t sem, int* value); ​ #ifdef __cplusplus } #endif ​ #endif /* THREAD_LINUX_H */ ​

log.c

#include "log.h" #include <stdio.h> #include <stdarg.h> #include <time.h> ​ /* 全局状态结构体 */ static struct { log_base_level_t current_level; /* 当前日志级别 */ bool console_output; /* 是否输出到控制台 */ bool initialized; /* 是否已初始化 */ } g_log = { LOG_BASE_LEVEL_INFO, /* 默认级别为INFO */ true, /* 默认输出到控制台 */ false /* 默认未初始化 */ }; ​ /** * @brief 初始化日志模块 * @param buffer_size 日志缓冲区大小(字节) * @return true 初始化成功 * @return false 初始化失败 */ bool log_init(size_t buffer_size) { /* 检查是否已初始化 */ if (g_log.initialized) { /* 已初始化,返回失败 */ return false; } /* 设置默认值 */ g_log.current_level = LOG_BASE_LEVEL_INFO; g_log.console_output = true; g_log.initialized = true; /* 记录初始化日志 */ base_log(LOG_BASE_LEVEL_INFO, "LOG_BASE", "Log module initialized"); /* 返回成功 */ return true; } ​ /** * @brief 销毁日志模块 */ void log_destroy(void) { /* 检查是否已初始化 */ if (!g_log.initialized) { /* 未初始化,直接返回 */ return; } /* 记录销毁日志 */ base_log(LOG_BASE_LEVEL_INFO, "LOG_BASE", "Log module destroyed"); /* 重置状态 */ g_log.initialized = false; } ​ /** * @brief 记录日志 * @param level 日志级别 * @param module 模块名称 * @param format 格式字符串 * @param ... 可变参数 */ void base_log(log_base_level_t level, const char* module, const char* format, ...) { /* 检查是否已初始化 */ if (!g_log.initialized) { return; } /* 检查日志级别 */ if (level < g_log.current_level) { return; } /* 检查是否启用控制台输出 */ if (!g_log.console_output) { return; } /* 获取当前时间 */ time_t now = time(NULL); /* 转换为本地时间 */ struct tm* tm_info = localtime(&now); /* 打印时间戳 */ printf("[%02d:%02d:%02d] ", tm_info->tm_hour, tm_info->tm_min, tm_info->tm_sec); /* 确定级别字符串 */ const char* level_str = "DEBUG"; if (level == LOG_BASE_LEVEL_INFO) level_str = "INFO"; else if (level == LOG_BASE_LEVEL_WARN) level_str = "WARN"; else if (level == LOG_BASE_LEVEL_ERROR) level_str = "ERROR"; else if (level == LOG_BASE_LEVEL_FATAL) level_str = "FATAL"; /* 打印级别和模块 */ printf("%s [%s] ", level_str, module ? module : "UNKNOWN"); /* 处理可变参数 */ va_list args; va_start(args, format); /* 打印日志内容 */ vprintf(format, args); /* 清理可变参数 */ va_end(args); /* 换行 */ printf("\n"); /* 错误级别立即刷新 */ if (level >= LOG_BASE_LEVEL_ERROR) { fflush(stdout); } } ​ /** * @brief 设置日志级别 * @param level 要设置的日志级别 */ void log_set_level(log_base_level_t level) { /* 检查级别是否有效 */ if (level >= LOG_BASE_LEVEL_DEBUG && level <= LOG_BASE_LEVEL_FATAL) { /* 设置新级别 */ g_log.current_level = level; } } ​ /** * @brief 获取当前日志级别 * @return log_base_level_t 当前日志级别 */ log_base_level_t log_get_level(void) { /* 返回当前级别 */ return g_log.current_level; } ​ /** * @brief 设置控制台输出 * @param enable true启用控制台输出,false禁用 */ void log_set_console_output(bool enable) { /* 设置控制台输出状态 */ g_log.console_output = enable; } ​

memory.c

/** * @file memory.c * @brief 内存追踪模块实现 * * 本模块实现内存分配追踪功能,替换标准的内存分配函数。 * 支持检测内存泄漏、重复释放和无效释放。 */ ​ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include <assert.h> #include "memory.h" #include "log.h" ​ /** @brief 最大追踪的内存分配数量 */ #define MAX_TRACKED_ALLOCATIONS 2048 ​ /** @brief 内存模块的日志模块名称 */ #define MEMORY_MODULE_NAME "MEMORY" ​ /** @brief 调用者信息获取宏 */ #define GET_CALLER_INFO() __FILE__, __LINE__, __func__ ​ /** * @brief 内存分配记录结构 */ typedef struct { void* ptr; /**< 分配的内存指针 */ size_t size; /**< 分配的大小(字节) */ const char* file; /**< 分配所在的源文件 */ int line; /**< 分配所在的行号 */ const char* function; /**< 分配所在的函数名 */ time_t timestamp; /**< 分配的时间戳 */ bool valid; /**< 记录是否有效 */ } AllocationRecord; ​ /** * @brief 内存追踪器全局状态 */ static struct { AllocationRecord records[MAX_TRACKED_ALLOCATIONS]; /**< 分配记录数组 */ size_t count; /**< 当前有效的记录数量 */ size_t current_total; /**< 当前分配的内存总量 */ size_t peak_total; /**< 峰值内存使用量 */ size_t total_allocations; /**< 总分配次数 */ size_t total_frees; /**< 总释放次数 */ size_t failed_frees; /**< 释放失败次数 */ bool tracking_enabled; /**< 是否启用追踪 */ bool initialized; /**< 模块是否已初始化 */ } g_memory_tracker = { .records = {{0}}, .count = 0, .current_total = 0, .peak_total = 0, .total_allocations = 0, .total_frees = 0, .failed_frees = 0, .tracking_enabled = false, .initialized = false }; ​ /** * @brief 内部函数:查找内存指针在记录中的索引 * * 这个函数会查找所有记录(包括已标记为无效的), * 用于检测重复释放。 * * @param ptr 要查找的内存指针 * @return int 找到返回索引,未找到返回-1 */ static int find_allocation_index(void* ptr) { if (ptr == NULL) { return -1; } for (int i = 0; i < MAX_TRACKED_ALLOCATIONS; i++) { /* 检查指针是否匹配,不管valid状态 */ if (g_memory_tracker.records[i].ptr == ptr) { return i; } } return -1; } ​ /** * @brief 内部函数:添加内存分配记录 * * @param ptr 分配的内存指针 * @param size 分配的大小 * @param file 源文件名 * @param line 行号 * @param function 函数名 * @return true 添加成功 * @return false 添加失败(记录已满) */ static bool add_allocation_record(void* ptr, size_t size, const char* file, int line, const char* function) { if (g_memory_tracker.count >= MAX_TRACKED_ALLOCATIONS) { base_log(LOG_BASE_LEVEL_ERROR, MEMORY_MODULE_NAME, "无法追踪更多内存分配,已达到最大限制 %d", MAX_TRACKED_ALLOCATIONS); return false; } /* 查找空闲位置 */ int index = -1; for (int i = 0; i < MAX_TRACKED_ALLOCATIONS; i++) { if (!g_memory_tracker.records[i].valid) { index = i; break; } } if (index == -1) { /* 理论上不会发生,因为count已经检查过了 */ base_log(LOG_BASE_LEVEL_ERROR, MEMORY_MODULE_NAME, "未找到空闲的记录位置"); return false; } /* 填充记录信息 */ g_memory_tracker.records[index].ptr = ptr; g_memory_tracker.records[index].size = size; g_memory_tracker.records[index].file = file; g_memory_tracker.records[index].line = line; g_memory_tracker.records[index].function = function; g_memory_tracker.records[index].timestamp = time(NULL); g_memory_tracker.records[index].valid = true; /* 更新统计信息 */ g_memory_tracker.count++; g_memory_tracker.current_total += size; g_memory_tracker.total_allocations++; /* 更新峰值内存使用量 */ if (g_memory_tracker.current_total > g_memory_tracker.peak_total) { g_memory_tracker.peak_total = g_memory_tracker.current_total; } /* 记录调试信息 */ base_log(LOG_BASE_LEVEL_DEBUG, MEMORY_MODULE_NAME, "分配内存: %p, 大小: %zu bytes, 位置: %s:%d %s()", ptr, size, file, line, function); return true; } ​ /** * @brief 内部函数:移除内存分配记录 * * @param ptr 要释放的内存指针 * @param file 源文件名 * @param line 行号 * @param function 函数名 * @return true 移除成功(第一次释放) * @return false 移除失败(重复释放或无效指针) */ static bool remove_allocation_record(void* ptr, const char* file, int line, const char* function) { if (ptr == NULL) { base_log(LOG_BASE_LEVEL_WARN, MEMORY_MODULE_NAME, "尝试释放空指针,位置: %s:%d %s()", file, line, function); return false; } int index = find_allocation_index(ptr); if (index == -1) { /* 情况1:指针从未被追踪过(可能是标准malloc分配的) */ base_log(LOG_BASE_LEVEL_WARN, MEMORY_MODULE_NAME, "释放未追踪的内存指针: %p, 位置: %s:%d %s()", ptr, file, line, function); g_memory_tracker.failed_frees++; return false; } /* 检查记录是否有效 */ if (!g_memory_tracker.records[index].valid) { /* 情况2:记录存在但已标记为无效,说明这是重复释放 */ base_log(LOG_BASE_LEVEL_ERROR, MEMORY_MODULE_NAME, "重复释放内存指针: %p\n" " 原分配位置: %s:%d %s()\n" " 当前释放位置: %s:%d %s()\n" " 原分配时间: %s", ptr, g_memory_tracker.records[index].file, g_memory_tracker.records[index].line, g_memory_tracker.records[index].function, file, line, function, ctime(&g_memory_tracker.records[index].timestamp)); g_memory_tracker.failed_frees++; return false; } /* 情况3:正常释放,第一次释放这个指针 */ /* 更新统计信息 */ g_memory_tracker.current_total -= g_memory_tracker.records[index].size; g_memory_tracker.total_frees++; /* 记录调试信息 */ base_log(LOG_BASE_LEVEL_DEBUG, MEMORY_MODULE_NAME, "释放内存: %p, 大小: %zu bytes\n" " 分配位置: %s:%d %s()\n" " 释放位置: %s:%d %s()", ptr, g_memory_tracker.records[index].size, g_memory_tracker.records[index].file, g_memory_tracker.records[index].line, g_memory_tracker.records[index].function, file, line, function); /* 标记记录为无效(但保留信息用于调试) */ g_memory_tracker.records[index].valid = false; g_memory_tracker.count--; return true; } ​ /** * @brief 内部函数:更新重新分配的记录 * * @param old_ptr 旧的内存指针 * @param new_ptr 新的内存指针 * @param new_size 新的大小 * @param file 源文件名 * @param line 行号 * @param function 函数名 * @return true 更新成功 * @return false 更新失败 */ static bool update_allocation_record(void* old_ptr, void* new_ptr, size_t new_size, const char* file, int line, const char* function) { if (old_ptr == NULL) { /* 相当于malloc */ return add_allocation_record(new_ptr, new_size, file, line, function); } if (new_ptr == NULL) { /* realloc失败,旧指针仍然有效 */ base_log(LOG_BASE_LEVEL_WARN, MEMORY_MODULE_NAME, "realloc失败,保持原指针: %p, 位置: %s:%d %s()", old_ptr, file, line, function); return false; } int index = find_allocation_index(old_ptr); if (index == -1) { /* 旧指针未追踪,直接添加新记录 */ base_log(LOG_BASE_LEVEL_WARN, MEMORY_MODULE_NAME, "realloc未追踪的旧指针: %p, 添加新记录: %p, 位置: %s:%d %s()", old_ptr, new_ptr, file, line, function); return add_allocation_record(new_ptr, new_size, file, line, function); } /* 更新记录信息 */ size_t old_size = g_memory_tracker.records[index].size; /* 更新当前内存总量 */ g_memory_tracker.current_total = g_memory_tracker.current_total - old_size + new_size; /* 更新记录 */ g_memory_tracker.records[index].ptr = new_ptr; g_memory_tracker.records[index].size = new_size; g_memory_tracker.records[index].file = file; g_memory_tracker.records[index].line = line; g_memory_tracker.records[index].function = function; g_memory_tracker.records[index].timestamp = time(NULL); g_memory_tracker.records[index].valid = true; /* 更新峰值内存使用量 */ if (g_memory_tracker.current_total > g_memory_tracker.peak_total) { g_memory_tracker.peak_total = g_memory_tracker.current_total; } /* 记录调试信息 */ base_log(LOG_BASE_LEVEL_DEBUG, MEMORY_MODULE_NAME, "重新分配内存: %p -> %p, 大小: %zu -> %zu bytes, 位置: %s:%d %s()", old_ptr, new_ptr, old_size, new_size, file, line, function); return true; } ​ /* ==================== 公共接口实现 ==================== */ ​ /** * @brief 初始化内存追踪模块 * * @return true 初始化成功 * @return false 初始化失败 */ bool memory_init(void) { if (g_memory_tracker.initialized) { base_log(LOG_BASE_LEVEL_WARN, MEMORY_MODULE_NAME, "内存追踪模块已初始化"); return true; } /* 初始化记录数组 */ for (int i = 0; i < MAX_TRACKED_ALLOCATIONS; i++) { g_memory_tracker.records[i].valid = false; } g_memory_tracker.count = 0; g_memory_tracker.current_total = 0; g_memory_tracker.peak_total = 0; g_memory_tracker.total_allocations = 0; g_memory_tracker.total_frees = 0; g_memory_tracker.failed_frees = 0; g_memory_tracker.tracking_enabled = true; g_memory_tracker.initialized = true; base_log(LOG_BASE_LEVEL_INFO, MEMORY_MODULE_NAME, "内存追踪模块初始化成功,最大追踪数量: %d", MAX_TRACKED_ALLOCATIONS); return true; } ​ /** * @brief 销毁内存追踪模块 */ void memory_destroy(void) { if (!g_memory_tracker.initialized) { return; } /* 检查内存泄漏 */ size_t leak_count = memory_check_leaks(); if (leak_count > 0) { base_log(LOG_BASE_LEVEL_ERROR, MEMORY_MODULE_NAME, "发现 %zu 处内存泄漏", leak_count); memory_print_leak_details(); } /* 打印最终统计信息 */ memory_print_stats(); /* 重置状态 */ g_memory_tracker.initialized = false; g_memory_tracker.tracking_enabled = false; base_log(LOG_BASE_LEVEL_INFO, MEMORY_MODULE_NAME, "内存追踪模块已销毁"); } ​ /** * @brief 启用或禁用内存追踪 * * @param enable true启用追踪,false禁用追踪 */ void memory_set_tracking(bool enable) { if (!g_memory_tracker.initialized) { base_log(LOG_BASE_LEVEL_WARN, MEMORY_MODULE_NAME, "内存追踪模块未初始化,无法设置追踪状态"); return; } g_memory_tracker.tracking_enabled = enable; base_log(LOG_BASE_LEVEL_INFO, MEMORY_MODULE_NAME, "内存追踪已%s", enable ? "启用" : "禁用"); } ​ /** * @brief 获取当前是否启用了内存追踪 * * @return true 已启用 * @return false 未启用 */ bool memory_is_tracking_enabled(void) { return g_memory_tracker.initialized && g_memory_tracker.tracking_enabled; } ​ /** * @brief 分配内存(替换标准malloc) * * 分配指定大小的内存块,并记录分配信息。 * 如果内存追踪未启用,则直接调用标准malloc。 * * @param size 要分配的字节数 * @return void* 指向分配内存的指针,失败返回NULL */ void* memory_malloc(size_t size) { void* ptr = malloc(size); if (ptr != NULL && memory_is_tracking_enabled()) { if (!add_allocation_record(ptr, size, GET_CALLER_INFO())) { /* 如果添加记录失败,释放内存并返回NULL */ free(ptr); return NULL; } } return ptr; } ​ /** * @brief 分配并清零内存(替换标准calloc) * * 分配指定数量和大小的内存块,并初始化为0。 * 如果内存追踪未启用,则直接调用标准calloc。 * * @param nmemb 元素数量 * @param size 每个元素的大小 * @return void* 指向分配内存的指针,失败返回NULL */ void* memory_calloc(size_t nmemb, size_t size) { void* ptr = calloc(nmemb, size); if (ptr != NULL && memory_is_tracking_enabled()) { size_t total_size = nmemb * size; if (!add_allocation_record(ptr, total_size, GET_CALLER_INFO())) { free(ptr); return NULL; } } return ptr; } ​ /** * @brief 重新分配内存(替换标准realloc) * * 调整已分配内存块的大小。 * 如果内存追踪未启用,则直接调用标准realloc。 * * @param ptr 要调整的内存指针 * @param size 新的字节数 * @return void* 指向重新分配内存的指针,失败返回NULL */ void* memory_realloc(void* ptr, size_t size) { void* new_ptr = realloc(ptr, size); if (memory_is_tracking_enabled()) { update_allocation_record(ptr, new_ptr, size, GET_CALLER_INFO()); } return new_ptr; } ​ /** * @brief 释放内存(替换标准free) * * 释放先前分配的内存块,并检查是否重复释放。 * 如果内存追踪未启用,则直接调用标准free。 * 如果指针已经释放过,会记录错误并直接返回,防止重复释放。 * * @param ptr 要释放的内存指针 */ void memory_free(void* ptr) { if (ptr == NULL) { base_log(LOG_BASE_LEVEL_DEBUG, MEMORY_MODULE_NAME, "尝试释放空指针,直接返回"); return; } if (!memory_is_tracking_enabled()) { free(ptr); return; } /* * 检查是否已经释放过 * remove_allocation_record 返回false表示: * 1. 重复释放(记录已标记为无效) * 2. 未追踪的指针 * 在这两种情况下都不应该再次调用free */ if (!remove_allocation_record(ptr, GET_CALLER_INFO())) { base_log(LOG_BASE_LEVEL_ERROR, MEMORY_MODULE_NAME, "放弃释放内存指针: %p,可能重复释放或无效指针", ptr); return; } /* 只有成功移除记录的情况下才实际释放内存 */ free(ptr); } ​ /** * @brief 检查内存泄漏 * * 检查当前是否有未释放的内存块。 * * @return size_t 泄漏的内存块数量 */ size_t memory_check_leaks(void) { size_t leak_count = 0; for (int i = 0; i < MAX_TRACKED_ALLOCATIONS; i++) { if (g_memory_tracker.records[i].valid) { leak_count++; } } return leak_count; } ​ /** * @brief 打印内存统计信息 */ void memory_print_stats(void) { if (!g_memory_tracker.initialized) { printf("内存追踪模块未初始化\n"); return; } printf("\n========== 内存统计信息 ==========\n"); printf("当前已分配内存: %zu bytes\n", g_memory_tracker.current_total); printf("峰值内存使用: %zu bytes\n", g_memory_tracker.peak_total); printf("总分配次数: %zu\n", g_memory_tracker.total_allocations); printf("总释放次数: %zu\n", g_memory_tracker.total_frees); printf("释放失败次数: %zu\n", g_memory_tracker.failed_frees); printf("当前追踪数量: %zu/%d\n", g_memory_tracker.count, MAX_TRACKED_ALLOCATIONS); printf("内存泄漏数量: %zu\n", memory_check_leaks()); printf("===================================\n"); } ​ /** * @brief 打印详细泄漏信息 */ void memory_print_leak_details(void) { size_t leak_count = 0; size_t total_leak_size = 0; printf("\n========== 内存泄漏详情 ==========\n"); for (int i = 0; i < MAX_TRACKED_ALLOCATIONS; i++) { if (g_memory_tracker.records[i].valid) { AllocationRecord* record = &g_memory_tracker.records[i]; printf("泄漏 #%zu:\n", ++leak_count); printf(" 地址: %p\n", record->ptr); printf(" 大小: %zu bytes\n", record->size); printf(" 位置: %s:%d\n", record->file, record->line); printf(" 函数: %s()\n", record->function); char time_str[64]; struct tm* tm_info = localtime(&record->timestamp); strftime(time_str, sizeof(time_str), "%Y-%m-%d %H:%M:%S", tm_info); printf(" 时间: %s\n", time_str); printf("\n"); total_leak_size += record->size; } } if (leak_count == 0) { printf("未发现内存泄漏\n"); } else { printf("总计: %zu 处泄漏,共 %zu bytes\n", leak_count, total_leak_size); } printf("==================================\n"); } ​ /** * @brief 获取当前已分配内存总量 * * @return size_t 当前分配的字节数 */ size_t memory_get_current_total(void) { return g_memory_tracker.current_total; } ​ /** * @brief 获取峰值内存使用量 * * @return size_t 峰值分配的字节数 */ size_t memory_get_peak_total(void) { return g_memory_tracker.peak_total; } ​ /** * @brief 获取总分配次数 * * @return size_t 分配调用次数 */ size_t memory_get_allocation_count(void) { return g_memory_tracker.total_allocations; } ​ /** * @brief 获取总释放次数 * * @return size_t 释放调用次数 */ size_t memory_get_free_count(void) { return g_memory_tracker.total_frees; } ​ /** * @brief 获取释放失败次数 * * 包括重复释放、无效指针等。 * * @return size_t 释放失败次数 */ size_t memory_get_failed_free_count(void) { return g_memory_tracker.failed_frees; } ​

thread_linux.c

/** * @file thread_linux.c * @brief Linux 线程通用接口封装实现 * * 基于 pthread 库的线程封装,集成日志和内存追踪。 * 仅使用标准 Linux/POSIX 接口。 */ ​ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <pthread.h> #include <unistd.h> #include <sys/syscall.h> #include <sys/time.h> #include <errno.h> #include <semaphore.h> #include <time.h> #include "thread_linux.h" #include "log.h" #include "memory.h" ​ /** @brief 线程模块的日志模块名称 */ #define THREAD_MODULE_NAME "THREAD" ​ /** @brief 最大线程名称长度 */ #define MAX_THREAD_NAME_LEN 32 ​ /** @brief 默认线程栈大小(字节) */ #define DEFAULT_STACK_SIZE (256 * 1024) /* 256KB */ ​ /** @brief 获取调用者信息宏 */ #define GET_CALLER_INFO() __FILE__, __LINE__, __func__ ​ /** * @brief 线程内部信息结构 */ typedef struct thread_info { pthread_t thread_id; /**< pthread线程ID */ thread_func_t func; /**< 线程函数 */ void* arg; /**< 线程参数 */ char name[MAX_THREAD_NAME_LEN]; /**< 线程名称 */ thread_state_t state; /**< 线程状态 */ bool detached; /**< 是否分离 */ void* retval; /**< 线程返回值 */ struct thread_info* next; /**< 链表指针 */ } thread_info_t; ​ /** * @brief 互斥锁内部结构 */ typedef struct { pthread_mutex_t mutex; /**< pthread互斥锁 */ char name[MAX_THREAD_NAME_LEN]; /**< 互斥锁名称(调试用) */ } mutex_info_t; ​ /** * @brief 条件变量内部结构 */ typedef struct { pthread_cond_t cond; /**< pthread条件变量 */ char name[MAX_THREAD_NAME_LEN]; /**< 条件变量名称(调试用) */ } cond_info_t; ​ /** * @brief 信号量内部结构 */ typedef struct { sem_t sem; /**< POSIX信号量 */ char name[MAX_THREAD_NAME_LEN]; /**< 信号量名称(调试用) */ } sem_info_t; ​ /** * @brief 线程管理器全局状态 */ typedef struct { bool initialized; /**< 模块是否已初始化 */ thread_info_t* thread_list; /**< 线程链表头指针 */ pthread_mutex_t list_mutex; /**< 保护线程链表的互斥锁 */ size_t thread_counter; /**< 线程计数器(用于生成默认名称) */ size_t mutex_counter; /**< 互斥锁计数器 */ size_t cond_counter; /**< 条件变量计数器 */ size_t sem_counter; /**< 信号量计数器 */ } thread_manager_t; ​ /** @brief 全局线程管理器实例 */ static thread_manager_t g_thread_manager = { .initialized = false, .thread_list = NULL, .list_mutex = PTHREAD_MUTEX_INITIALIZER, .thread_counter = 0, .mutex_counter = 0, .cond_counter = 0, .sem_counter = 0 }; ​ /* ==================== 内部辅助函数 ==================== */ ​ /** * @brief 内部函数:获取当前时间戳(毫秒) * * 使用标准的 clock_gettime 函数,支持 CLOCK_MONOTONIC。 * * @return unsigned long long 当前时间戳(毫秒) */ #if 0 static unsigned long long get_current_time_ms(void) { struct timespec ts; /* 使用单调时钟,不受系统时间调整影响 */ if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) { /* 如果失败,使用实时时钟作为备用 */ clock_gettime(CLOCK_REALTIME, &ts); } return (unsigned long long)ts.tv_sec * 1000 + ts.tv_nsec / 1000000; } #endif ​ /** * @brief 内部函数:将错误码转换为字符串 * * @param error 错误码 * @return const char* 错误描述 */ static const char* error_to_string(thread_error_t error) { switch (error) { case THREAD_SUCCESS: return "Success"; case THREAD_ERROR_INIT: return "Module initialization failed"; case THREAD_ERROR_MEMORY: return "Memory allocation failed"; case THREAD_ERROR_CREATE: return "Thread creation failed"; case THREAD_ERROR_PARAM: return "Invalid parameter"; case THREAD_ERROR_NOT_FOUND: return "Thread not found"; case THREAD_ERROR_DEADLOCK: return "Potential deadlock detected"; case THREAD_ERROR_TIMEOUT: return "Operation timeout"; case THREAD_ERROR_SYSTEM: return "System call failed"; default: return "Unknown error"; } } ​ /** * @brief 内部函数:生成默认线程名称 * * 根据前缀和计数器生成唯一的名称。 * * @param buffer 输出缓冲区 * @param size 缓冲区大小 * @param counter 计数器指针 * @param prefix 名称前缀 */ static void generate_default_name(char* buffer, size_t size, size_t* counter, const char* prefix) { if (buffer == NULL || size == 0 || counter == NULL || prefix == NULL) { return; } /* 使用原子操作保证线程安全 */ size_t index = __sync_fetch_and_add(counter, 1); snprintf(buffer, size, "%s-%zu", prefix, index); } ​ /** * @brief 内部函数:在线程链表中查找线程信息 * * @param thread_id pthread线程ID * @return thread_info_t* 线程信息指针,未找到返回NULL */ static thread_info_t* find_thread_info(pthread_t thread_id) { thread_info_t* current = g_thread_manager.thread_list; while (current != NULL) { if (pthread_equal(current->thread_id, thread_id)) { return current; } current = current->next; } return NULL; } ​ /** * @brief 内部函数:在线程链表中添加线程信息 * * @param info 线程信息指针 * @return thread_error_t 错误码 */ static thread_error_t add_thread_info(thread_info_t* info) { if (info == NULL) { return THREAD_ERROR_PARAM; } pthread_mutex_lock(&g_thread_manager.list_mutex); /* 添加到链表头部 */ info->next = g_thread_manager.thread_list; g_thread_manager.thread_list = info; pthread_mutex_unlock(&g_thread_manager.list_mutex); base_log(LOG_BASE_LEVEL_DEBUG, THREAD_MODULE_NAME, "添加线程信息到链表: %s (ID: %lu)", info->name, (unsigned long)info->thread_id); return THREAD_SUCCESS; } ​ /** * @brief 内部函数:从线程链表中移除线程信息 * * @param thread_id pthread线程ID * @return thread_info_t* 被移除的线程信息指针,未找到返回NULL */ static thread_info_t* remove_thread_info(pthread_t thread_id) { thread_info_t* current = g_thread_manager.thread_list; thread_info_t* prev = NULL; pthread_mutex_lock(&g_thread_manager.list_mutex); while (current != NULL) { if (pthread_equal(current->thread_id, thread_id)) { /* 从链表中移除 */ if (prev == NULL) { g_thread_manager.thread_list = current->next; } else { prev->next = current->next; } pthread_mutex_unlock(&g_thread_manager.list_mutex); base_log(LOG_BASE_LEVEL_DEBUG, THREAD_MODULE_NAME, "从链表移除线程信息: %s (ID: %lu)", current->name, (unsigned long)thread_id); return current; } prev = current; current = current->next; } pthread_mutex_unlock(&g_thread_manager.list_mutex); return NULL; } ​ /** * @brief 内部函数:计算超时的绝对时间 * * 将相对的超时时间转换为绝对的 timespec 结构。 * * @param timeout_ms 超时时间(毫秒) * @param abstime 输出参数,接收绝对时间 */ static void calculate_abstime(unsigned int timeout_ms, struct timespec* abstime) { if (abstime == NULL) { return; } /* 获取当前时间 */ clock_gettime(CLOCK_REALTIME, abstime); /* 添加超时时间 */ abstime->tv_sec += timeout_ms / 1000; abstime->tv_nsec += (timeout_ms % 1000) * 1000000; /* 处理纳秒溢出 */ if (abstime->tv_nsec >= 1000000000) { abstime->tv_sec += 1; abstime->tv_nsec -= 1000000000; } } ​ /** * @brief 内部函数:线程包装函数 * * pthread_create 要求的函数签名,包装用户线程函数。 * 使用标准的 POSIX 接口,不依赖 GNU 扩展。 * * @param arg ThreadInfo指针 * @return void* 线程返回值 */ static void* thread_wrapper(void* arg) { thread_info_t* info = (thread_info_t*)arg; void* retval = NULL; base_log(LOG_BASE_LEVEL_INFO, THREAD_MODULE_NAME, "线程 [%s] 开始执行, 线程ID: %lu", info->name, (unsigned long)info->thread_id); /* 更新线程状态 */ info->state = THREAD_STATE_RUNNING; /* 设置线程取消状态(使线程可被取消) */ pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL); /* 调用用户线程函数 */ if (info->func != NULL) { retval = info->func(info->arg); } else { base_log(LOG_BASE_LEVEL_WARN, THREAD_MODULE_NAME, "线程 [%s] 的函数指针为NULL", info->name); } /* 保存返回值 */ info->retval = retval; /* 更新线程状态 */ info->state = THREAD_STATE_TERMINATED; base_log(LOG_BASE_LEVEL_INFO, THREAD_MODULE_NAME, "线程 [%s] 执行结束, 返回值: %p", info->name, retval); /* 如果线程是分离的,自动清理资源 */ if (info->detached) { thread_info_t* removed = remove_thread_info(info->thread_id); if (removed != NULL) { memory_free(removed); } else { /* 如果未在链表中找到,仍然需要清理 */ memory_free(info); } } /* 返回线程执行结果 */ return retval; } ​ /* ==================== 模块初始化和销毁 ==================== */ ​ /** * @brief 初始化线程模块 * * 必须在调用任何线程函数之前调用此函数。 * * @return thread_error_t 错误码,THREAD_SUCCESS表示成功 */ thread_error_t thread_module_init(void) { /* 检查是否已经初始化 */ if (g_thread_manager.initialized) { base_log(LOG_BASE_LEVEL_WARN, THREAD_MODULE_NAME, "线程模块已经初始化"); return THREAD_SUCCESS; } /* 初始化链表互斥锁 */ int result = pthread_mutex_init(&g_thread_manager.list_mutex, NULL); if (result != 0) { base_log(LOG_BASE_LEVEL_ERROR, THREAD_MODULE_NAME, "初始化链表互斥锁失败: %s", strerror(result)); return THREAD_ERROR_INIT; } /* 重置所有计数器 */ g_thread_manager.thread_counter = 0; g_thread_manager.mutex_counter = 0; g_thread_manager.cond_counter = 0; g_thread_manager.sem_counter = 0; /* 初始化线程链表 */ g_thread_manager.thread_list = NULL; g_thread_manager.initialized = true; base_log(LOG_BASE_LEVEL_INFO, THREAD_MODULE_NAME, "线程模块初始化成功"); return THREAD_SUCCESS; } ​ /** * @brief 销毁线程模块 * * 释放所有资源,应在程序退出前调用。 * 会检查是否有未销毁的线程和同步对象。 */ void thread_module_destroy(void) { if (!g_thread_manager.initialized) { base_log(LOG_BASE_LEVEL_WARN, THREAD_MODULE_NAME, "线程模块未初始化,无需销毁"); return; } base_log(LOG_BASE_LEVEL_INFO, THREAD_MODULE_NAME, "开始销毁线程模块"); ​ /* 检查是否有未销毁的线程 */ int active_threads = 0; int leaked_mutexes = 0; int leaked_conds = 0; int leaked_sems = 0; ​ /* 先取消所有未结束的线程 */ pthread_mutex_lock(&g_thread_manager.list_mutex); thread_info_t* current = g_thread_manager.thread_list; while (current != NULL) { if (current->state != THREAD_STATE_TERMINATED && current->state != THREAD_STATE_DETACHED) { base_log(LOG_BASE_LEVEL_WARN, THREAD_MODULE_NAME, "取消未结束的线程: %s", current->name); pthread_cancel(current->thread_id); } current = current->next; } pthread_mutex_unlock(&g_thread_manager.list_mutex); /* 等待一小段时间让线程响应取消 */ thread_sleep(500); /* 报告泄漏情况 */ if (active_threads > 0) { base_log(LOG_BASE_LEVEL_ERROR, THREAD_MODULE_NAME, "发现 %d 个未结束的线程", active_threads); } if (leaked_mutexes > 0) { base_log(LOG_BASE_LEVEL_ERROR, THREAD_MODULE_NAME, "发现 %d 个未销毁的互斥锁", leaked_mutexes); } if (leaked_conds > 0) { base_log(LOG_BASE_LEVEL_ERROR, THREAD_MODULE_NAME, "发现 %d 个未销毁的条件变量", leaked_conds); } if (leaked_sems > 0) { base_log(LOG_BASE_LEVEL_ERROR, THREAD_MODULE_NAME, "发现 %d 个未销毁的信号量", leaked_sems); } /* 销毁链表互斥锁 */ pthread_mutex_destroy(&g_thread_manager.list_mutex); /* 清理线程链表 */ pthread_mutex_lock(&g_thread_manager.list_mutex); current = g_thread_manager.thread_list; while (current != NULL) { thread_info_t* next = current->next; base_log(LOG_BASE_LEVEL_DEBUG, THREAD_MODULE_NAME, "清理线程资源: %s", current->name); memory_free(current); current = next; } g_thread_manager.thread_list = NULL; pthread_mutex_unlock(&g_thread_manager.list_mutex); /* 重置状态 */ g_thread_manager.initialized = false; base_log(LOG_BASE_LEVEL_INFO, THREAD_MODULE_NAME, "线程模块销毁完成"); } ​ /* ==================== 线程管理接口 ==================== */ ​ /** * @brief 创建线程 * * @param func 线程函数 * @param arg 传递给线程函数的参数 * @param name 线程名称(可选),NULL表示自动生成 * @param handle 输出参数,接收线程句柄 * @return thread_error_t 错误码 */ thread_error_t thread_create(thread_func_t func, void* arg, const char* name, thread_handle_t* handle) { return thread_create_ex(func, arg, name, 0, false, handle); } ​ /** * @brief 创建带属性的线程 * * @param func 线程函数 * @param arg 传递给线程函数的参数 * @param name 线程名称 * @param stack_size 栈大小(字节),0表示默认值 * @param detach_state 是否分离(true:分离, false:可连接) * @param handle 输出参数,接收线程句柄 * @return thread_error_t 错误码 */ thread_error_t thread_create_ex(thread_func_t func, void* arg, const char* name, size_t stack_size, bool detach_state, thread_handle_t* handle) { /* 参数检查 */ if (func == NULL) { base_log(LOG_BASE_LEVEL_ERROR, THREAD_MODULE_NAME, "线程函数不能为NULL"); return THREAD_ERROR_PARAM; } if (handle == NULL) { base_log(LOG_BASE_LEVEL_ERROR, THREAD_MODULE_NAME, "输出句柄不能为NULL"); return THREAD_ERROR_PARAM; } /* 检查模块是否初始化 */ if (!g_thread_manager.initialized) { base_log(LOG_BASE_LEVEL_ERROR, THREAD_MODULE_NAME, "线程模块未初始化"); return THREAD_ERROR_INIT; } /* 分配线程信息结构 */ thread_info_t* info = (thread_info_t*)memory_malloc(sizeof(thread_info_t)); if (info == NULL) { base_log(LOG_BASE_LEVEL_ERROR, THREAD_MODULE_NAME, "分配线程信息结构失败"); return THREAD_ERROR_MEMORY; } /* 初始化线程信息 */ memset(info, 0, sizeof(thread_info_t)); info->func = func; info->arg = arg; info->state = THREAD_STATE_CREATED; info->detached = detach_state; info->retval = NULL; info->next = NULL; /* 设置线程名称 */ if (name != NULL && name[0] != '\0') { strncpy(info->name, name, MAX_THREAD_NAME_LEN - 1); info->name[MAX_THREAD_NAME_LEN - 1] = '\0'; } else { generate_default_name(info->name, MAX_THREAD_NAME_LEN, &g_thread_manager.thread_counter, "Thread"); } /* 设置线程属性 */ pthread_attr_t attr; int result = pthread_attr_init(&attr); if (result != 0) { base_log(LOG_BASE_LEVEL_ERROR, THREAD_MODULE_NAME, "初始化线程属性失败: %s", strerror(result)); memory_free(info); return THREAD_ERROR_SYSTEM; } /* 设置栈大小(如果指定) */ if (stack_size > 0) { result = pthread_attr_setstacksize(&attr, stack_size); if (result != 0) { base_log(LOG_BASE_LEVEL_WARN, THREAD_MODULE_NAME, "设置线程栈大小失败: %s,使用默认值", strerror(result)); } } /* 设置分离状态 */ if (detach_state) { result = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); if (result != 0) { base_log(LOG_BASE_LEVEL_WARN, THREAD_MODULE_NAME, "设置线程分离状态失败: %s", strerror(result)); } } /* 创建线程 */ result = pthread_create(&info->thread_id, &attr, thread_wrapper, info); /* 销毁线程属性 */ pthread_attr_destroy(&attr); if (result != 0) { base_log(LOG_BASE_LEVEL_ERROR, THREAD_MODULE_NAME, "创建线程失败: %s", strerror(result)); memory_free(info); return THREAD_ERROR_CREATE; } /* 添加到线程链表 */ thread_error_t err = add_thread_info(info); if (err != THREAD_SUCCESS) { base_log(LOG_BASE_LEVEL_ERROR, THREAD_MODULE_NAME, "添加线程信息到链表失败"); /* 注意:线程已经创建成功,不能取消,只能标记为分离 */ pthread_detach(info->thread_id); memory_free(info); return err; } /* 返回线程句柄 */ *handle = (thread_handle_t)info; base_log(LOG_BASE_LEVEL_INFO, THREAD_MODULE_NAME, "成功创建线程: %s (句柄: %p, ID: %lu)", info->name, info, (unsigned long)info->thread_id); return THREAD_SUCCESS; } ​ /** * @brief 等待线程结束 * * 阻塞当前线程,直到指定线程结束。 * * @param handle 线程句柄 * @param retval 输出参数,接收线程返回值,NULL表示不接收 * @return thread_error_t 错误码 */ thread_error_t thread_join(thread_handle_t handle, void** retval) { if (handle == NULL) { base_log(LOG_BASE_LEVEL_ERROR, THREAD_MODULE_NAME, "线程句柄不能为NULL"); return THREAD_ERROR_PARAM; } thread_info_t* info = (thread_info_t*)handle; /* 检查线程是否已经分离 */ if (info->detached) { base_log(LOG_BASE_LEVEL_ERROR, THREAD_MODULE_NAME, "线程 [%s] 是分离状态,无法等待", info->name); return THREAD_ERROR_PARAM; } /* 调用 pthread_join */ int result = pthread_join(info->thread_id, retval); if (result != 0) { base_log(LOG_BASE_LEVEL_ERROR, THREAD_MODULE_NAME, "等待线程 [%s] 失败: %s", info->name, strerror(result)); return THREAD_ERROR_SYSTEM; } /* 更新线程状态 */ info->state = THREAD_STATE_TERMINATED; /* 保存返回值(如果提供) */ if (retval != NULL) { info->retval = *retval; } base_log(LOG_BASE_LEVEL_INFO, THREAD_MODULE_NAME, "线程 [%s] 等待结束,返回值: %p", info->name, info->retval); return THREAD_SUCCESS; } ​ /** * @brief 分离线程 * * 将线程设置为分离状态,线程结束后自动回收资源。 * * @param handle 线程句柄 * @return thread_error_t 错误码 */ thread_error_t thread_detach(thread_handle_t handle) { if (handle == NULL) { base_log(LOG_BASE_LEVEL_ERROR, THREAD_MODULE_NAME, "线程句柄不能为NULL"); return THREAD_ERROR_PARAM; } thread_info_t* info = (thread_info_t*)handle; /* 检查线程是否已经分离 */ if (info->detached) { base_log(LOG_BASE_LEVEL_WARN, THREAD_MODULE_NAME, "线程 [%s] 已经是分离状态", info->name); return THREAD_SUCCESS; } /* 调用 pthread_detach */ int result = pthread_detach(info->thread_id); if (result != 0) { base_log(LOG_BASE_LEVEL_ERROR, THREAD_MODULE_NAME, "分离线程 [%s] 失败: %s", info->name, strerror(result)); return THREAD_ERROR_SYSTEM; } /* 更新线程信息 */ info->detached = true; info->state = THREAD_STATE_DETACHED; base_log(LOG_BASE_LEVEL_INFO, THREAD_MODULE_NAME, "线程 [%s] 已分离", info->name); return THREAD_SUCCESS; } ​ /** * @brief 取消线程 * * @param handle 线程句柄 * @return thread_error_t 错误码 */ thread_error_t thread_cancel(thread_handle_t handle) { if (handle == NULL) { base_log(LOG_BASE_LEVEL_ERROR, THREAD_MODULE_NAME, "线程句柄不能为NULL"); return THREAD_ERROR_PARAM; } thread_info_t* info = (thread_info_t*)handle; /* 检查线程是否已经结束 */ if (info->state == THREAD_STATE_TERMINATED || info->state == THREAD_STATE_DETACHED) { base_log(LOG_BASE_LEVEL_WARN, THREAD_MODULE_NAME, "线程 [%s] 已经结束,无需取消", info->name); return THREAD_SUCCESS; } /* 调用 pthread_cancel */ int result = pthread_cancel(info->thread_id); if (result != 0) { base_log(LOG_BASE_LEVEL_ERROR, THREAD_MODULE_NAME, "取消线程 [%s] 失败: %s", info->name, strerror(result)); return THREAD_ERROR_SYSTEM; } /* 给线程一点时间响应取消 */ thread_sleep(10); /* 更新线程状态 */ info->state = THREAD_STATE_TERMINATED; base_log(LOG_BASE_LEVEL_WARN, THREAD_MODULE_NAME, "已发送取消请求给线程 [%s]", info->name); return THREAD_SUCCESS; } ​ /** * @brief 获取当前线程句柄 * * @return thread_handle_t 当前线程句柄 */ thread_handle_t thread_self(void) { pthread_t self_id = pthread_self(); pthread_mutex_lock(&g_thread_manager.list_mutex); thread_info_t* info = find_thread_info(self_id); pthread_mutex_unlock(&g_thread_manager.list_mutex); /* 如果未找到,可能是线程不是通过本模块创建的 */ if (info == NULL) { base_log(LOG_BASE_LEVEL_DEBUG, THREAD_MODULE_NAME, "未找到当前线程的句柄 (ID: %lu)", (unsigned long)self_id); return NULL; } return (thread_handle_t)info; } ​ /** * @brief 获取线程状态 * * @param handle 线程句柄 * @param state 输出参数,接收线程状态 * @return thread_error_t 错误码 */ thread_error_t thread_get_state(thread_handle_t handle, thread_state_t* state) { if (handle == NULL) { base_log(LOG_BASE_LEVEL_ERROR, THREAD_MODULE_NAME, "线程句柄不能为NULL"); return THREAD_ERROR_PARAM; } if (state == NULL) { base_log(LOG_BASE_LEVEL_ERROR, THREAD_MODULE_NAME, "状态输出参数不能为NULL"); return THREAD_ERROR_PARAM; } thread_info_t* info = (thread_info_t*)handle; *state = info->state; return THREAD_SUCCESS; } ​ /** * @brief 获取线程名称 * * @param handle 线程句柄 * @param name 输出缓冲区 * @param size 缓冲区大小 * @return thread_error_t 错误码 */ thread_error_t thread_get_name(thread_handle_t handle, char* name, size_t size) { if (handle == NULL) { base_log(LOG_BASE_LEVEL_ERROR, THREAD_MODULE_NAME, "线程句柄不能为NULL"); return THREAD_ERROR_PARAM; } if (name == NULL || size == 0) { base_log(LOG_BASE_LEVEL_ERROR, THREAD_MODULE_NAME, "名称缓冲区无效"); return THREAD_ERROR_PARAM; } thread_info_t* info = (thread_info_t*)handle; strncpy(name, info->name, size - 1); name[size - 1] = '\0'; return THREAD_SUCCESS; } ​ /** * @brief 设置线程名称 * * 注意:这只是设置模块内部的名称,不是系统级的线程名称。 * * @param handle 线程句柄 * @param name 新的线程名称 * @return thread_error_t 错误码 */ thread_error_t thread_set_name(thread_handle_t handle, const char* name) { if (handle == NULL) { base_log(LOG_BASE_LEVEL_ERROR, THREAD_MODULE_NAME, "线程句柄不能为NULL"); return THREAD_ERROR_PARAM; } if (name == NULL || name[0] == '\0') { base_log(LOG_BASE_LEVEL_ERROR, THREAD_MODULE_NAME, "线程名称不能为空"); return THREAD_ERROR_PARAM; } thread_info_t* info = (thread_info_t*)handle; strncpy(info->name, name, MAX_THREAD_NAME_LEN - 1); info->name[MAX_THREAD_NAME_LEN - 1] = '\0'; base_log(LOG_BASE_LEVEL_INFO, THREAD_MODULE_NAME, "设置线程名称: %s", info->name); return THREAD_SUCCESS; } ​ /** * @brief 销毁线程句柄 * * 释放线程资源,但不终止线程本身。 * 线程必须已经终止或被分离。 * * @param handle 线程句柄 * @return thread_error_t 错误码 */ thread_error_t thread_destroy(thread_handle_t handle) { if (handle == NULL) { base_log(LOG_BASE_LEVEL_ERROR, THREAD_MODULE_NAME, "线程句柄不能为NULL"); return THREAD_ERROR_PARAM; } thread_info_t* info = (thread_info_t*)handle; /* 检查线程是否已经结束 */ if (info->state != THREAD_STATE_TERMINATED && info->state != THREAD_STATE_DETACHED) { base_log(LOG_BASE_LEVEL_ERROR, THREAD_MODULE_NAME, "线程 [%s] 尚未结束,不能销毁句柄", info->name); return THREAD_ERROR_PARAM; } /* 从链表中移除 */ thread_info_t* removed = remove_thread_info(info->thread_id); if (removed != NULL) { memory_free(removed); base_log(LOG_BASE_LEVEL_INFO, THREAD_MODULE_NAME, "销毁线程句柄: %s", info->name); return THREAD_SUCCESS; } else { base_log(LOG_BASE_LEVEL_WARN, THREAD_MODULE_NAME, "线程句柄未在链表中找到: %s", info->name); /* 仍然释放内存 */ memory_free(info); return THREAD_SUCCESS; } } ​ /** * @brief 让出CPU * * 当前线程主动放弃CPU,让其他线程运行。 */ void thread_yield(void) { sched_yield(); /* POSIX 标准函数 */ } ​ /** * @brief 睡眠指定毫秒数 * * @param milliseconds 睡眠的毫秒数 */ void thread_sleep(unsigned int milliseconds) { if (milliseconds == 0) { return; } struct timespec ts; ts.tv_sec = milliseconds / 1000; ts.tv_nsec = (milliseconds % 1000) * 1000000; /* 使用 nanosleep,它是 POSIX 标准函数 */ nanosleep(&ts, NULL); } ​ /** * @brief 获取错误码描述 * * @param error 错误码 * @return const char* 错误描述字符串 */ const char* thread_strerror(thread_error_t error) { return error_to_string(error); } ​ /* ==================== 互斥锁接口实现 ==================== */ ​ /** * @brief 创建互斥锁 * * @param mutex 输出参数,接收互斥锁句柄 * @return thread_error_t 错误码 */ thread_error_t thread_mutex_create(thread_mutex_t* mutex) { if (mutex == NULL) { return THREAD_ERROR_PARAM; } mutex_info_t* info = (mutex_info_t*)memory_malloc(sizeof(mutex_info_t)); if (info == NULL) { return THREAD_ERROR_MEMORY; } /* 初始化互斥锁 */ int result = pthread_mutex_init(&info->mutex, NULL); if (result != 0) { memory_free(info); return THREAD_ERROR_SYSTEM; } /* 生成名称 */ generate_default_name(info->name, MAX_THREAD_NAME_LEN, &g_thread_manager.mutex_counter, "Mutex"); *mutex = (thread_mutex_t)info; base_log(LOG_BASE_LEVEL_DEBUG, THREAD_MODULE_NAME, "创建互斥锁: %s", info->name); return THREAD_SUCCESS; } ​ /** * @brief 销毁互斥锁 * * @param mutex 互斥锁句柄 * @return thread_error_t 错误码 */ thread_error_t thread_mutex_destroy(thread_mutex_t mutex) { if (mutex == NULL) { return THREAD_ERROR_PARAM; } mutex_info_t* info = (mutex_info_t*)mutex; /* 销毁互斥锁 */ int result = pthread_mutex_destroy(&info->mutex); if (result != 0) { base_log(LOG_BASE_LEVEL_WARN, THREAD_MODULE_NAME, "销毁互斥锁失败: %s", strerror(result)); } base_log(LOG_BASE_LEVEL_DEBUG, THREAD_MODULE_NAME, "销毁互斥锁: %s", info->name); memory_free(info); return THREAD_SUCCESS; } ​ /** * @brief 锁定互斥锁 * * @param mutex 互斥锁句柄 * @return thread_error_t 错误码 */ thread_error_t thread_mutex_lock(thread_mutex_t mutex) { if (mutex == NULL) { return THREAD_ERROR_PARAM; } mutex_info_t* info = (mutex_info_t*)mutex; int result = pthread_mutex_lock(&info->mutex); if (result != 0) { base_log(LOG_BASE_LEVEL_ERROR, THREAD_MODULE_NAME, "锁定互斥锁失败: %s", strerror(result)); return THREAD_ERROR_SYSTEM; } return THREAD_SUCCESS; } ​ /** * @brief 解锁互斥锁 * * @param mutex 互斥锁句柄 * @return thread_error_t 错误码 */ thread_error_t thread_mutex_unlock(thread_mutex_t mutex) { if (mutex == NULL) { return THREAD_ERROR_PARAM; } mutex_info_t* info = (mutex_info_t*)mutex; int result = pthread_mutex_unlock(&info->mutex); if (result != 0) { base_log(LOG_BASE_LEVEL_ERROR, THREAD_MODULE_NAME, "解锁互斥锁失败: %s", strerror(result)); return THREAD_ERROR_SYSTEM; } return THREAD_SUCCESS; } ​ /** * @brief 尝试锁定互斥锁 * * @param mutex 互斥锁句柄 * @return thread_error_t 成功返回THREAD_SUCCESS,被锁定返回THREAD_ERROR_TIMEOUT */ thread_error_t thread_mutex_trylock(thread_mutex_t mutex) { if (mutex == NULL) { return THREAD_ERROR_PARAM; } mutex_info_t* info = (mutex_info_t*)mutex; int result = pthread_mutex_trylock(&info->mutex); if (result == EBUSY) { return THREAD_ERROR_TIMEOUT; } else if (result != 0) { return THREAD_ERROR_SYSTEM; } return THREAD_SUCCESS; } ​ /* ==================== 条件变量接口实现 ==================== */ ​ /** * @brief 创建条件变量 * * @param cond 输出参数,接收条件变量句柄 * @return thread_error_t 错误码 */ thread_error_t thread_cond_create(thread_cond_t* cond) { if (cond == NULL) { return THREAD_ERROR_PARAM; } cond_info_t* info = (cond_info_t*)memory_malloc(sizeof(cond_info_t)); if (info == NULL) { return THREAD_ERROR_MEMORY; } /* 初始化条件变量 */ int result = pthread_cond_init(&info->cond, NULL); if (result != 0) { memory_free(info); return THREAD_ERROR_SYSTEM; } /* 生成名称 */ generate_default_name(info->name, MAX_THREAD_NAME_LEN, &g_thread_manager.cond_counter, "Cond"); *cond = (thread_cond_t)info; base_log(LOG_BASE_LEVEL_DEBUG, THREAD_MODULE_NAME, "创建条件变量: %s", info->name); return THREAD_SUCCESS; } ​ /** * @brief 销毁条件变量 * * @param cond 条件变量句柄 * @return thread_error_t 错误码 */ thread_error_t thread_cond_destroy(thread_cond_t cond) { if (cond == NULL) { return THREAD_ERROR_PARAM; } cond_info_t* info = (cond_info_t*)cond; /* 销毁条件变量 */ int result = pthread_cond_destroy(&info->cond); if (result != 0) { base_log(LOG_BASE_LEVEL_WARN, THREAD_MODULE_NAME, "销毁条件变量失败: %s", strerror(result)); } base_log(LOG_BASE_LEVEL_DEBUG, THREAD_MODULE_NAME, "销毁条件变量: %s", info->name); memory_free(info); return THREAD_SUCCESS; } ​ /** * @brief 等待条件变量 * * @param cond 条件变量句柄 * @param mutex 关联的互斥锁句柄 * @return thread_error_t 错误码 */ thread_error_t thread_cond_wait(thread_cond_t cond, thread_mutex_t mutex) { if (cond == NULL || mutex == NULL) { return THREAD_ERROR_PARAM; } cond_info_t* cond_info = (cond_info_t*)cond; mutex_info_t* mutex_info = (mutex_info_t*)mutex; int result = pthread_cond_wait(&cond_info->cond, &mutex_info->mutex); if (result != 0) { base_log(LOG_BASE_LEVEL_ERROR, THREAD_MODULE_NAME, "等待条件变量失败: %s", strerror(result)); return THREAD_ERROR_SYSTEM; } return THREAD_SUCCESS; } ​ /** * @brief 带超时的等待条件变量 * * @param cond 条件变量句柄 * @param mutex 关联的互斥锁句柄 * @param timeout_ms 超时时间(毫秒) * @return thread_error_t 超时返回THREAD_ERROR_TIMEOUT */ thread_error_t thread_cond_timedwait(thread_cond_t cond, thread_mutex_t mutex, unsigned int timeout_ms) { if (cond == NULL || mutex == NULL) { return THREAD_ERROR_PARAM; } cond_info_t* cond_info = (cond_info_t*)cond; mutex_info_t* mutex_info = (mutex_info_t*)mutex; struct timespec ts; calculate_abstime(timeout_ms, &ts); int result = pthread_cond_timedwait(&cond_info->cond, &mutex_info->mutex, &ts); if (result == ETIMEDOUT) { return THREAD_ERROR_TIMEOUT; } else if (result != 0) { base_log(LOG_BASE_LEVEL_ERROR, THREAD_MODULE_NAME, "超时等待条件变量失败: %s", strerror(result)); return THREAD_ERROR_SYSTEM; } return THREAD_SUCCESS; } ​ /** * @brief 唤醒一个等待条件变量的线程 * * @param cond 条件变量句柄 * @return thread_error_t 错误码 */ thread_error_t thread_cond_signal(thread_cond_t cond) { if (cond == NULL) { return THREAD_ERROR_PARAM; } cond_info_t* info = (cond_info_t*)cond; int result = pthread_cond_signal(&info->cond); if (result != 0) { base_log(LOG_BASE_LEVEL_ERROR, THREAD_MODULE_NAME, "唤醒条件变量失败: %s", strerror(result)); return THREAD_ERROR_SYSTEM; } return THREAD_SUCCESS; } ​ /** * @brief 唤醒所有等待条件变量的线程 * * @param cond 条件变量句柄 * @return thread_error_t 错误码 */ thread_error_t thread_cond_broadcast(thread_cond_t cond) { if (cond == NULL) { return THREAD_ERROR_PARAM; } cond_info_t* info = (cond_info_t*)cond; int result = pthread_cond_broadcast(&info->cond); if (result != 0) { base_log(LOG_BASE_LEVEL_ERROR, THREAD_MODULE_NAME, "广播条件变量失败: %s", strerror(result)); return THREAD_ERROR_SYSTEM; } return THREAD_SUCCESS; } ​ /* ==================== 信号量接口实现 ==================== */ ​ /** * @brief 创建信号量 * * @param sem 输出参数,接收信号量句柄 * @param initial_value 初始值 * @return thread_error_t 错误码 */ thread_error_t thread_sem_create(thread_sem_t* sem, unsigned int initial_value) { if (sem == NULL) { return THREAD_ERROR_PARAM; } sem_info_t* info = (sem_info_t*)memory_malloc(sizeof(sem_info_t)); if (info == NULL) { return THREAD_ERROR_MEMORY; } /* 初始化信号量 */ int result = sem_init(&info->sem, 0, initial_value); if (result != 0) { memory_free(info); return THREAD_ERROR_SYSTEM; } /* 生成名称 */ generate_default_name(info->name, MAX_THREAD_NAME_LEN, &g_thread_manager.sem_counter, "Sem"); *sem = (thread_sem_t)info; base_log(LOG_BASE_LEVEL_DEBUG, THREAD_MODULE_NAME, "创建信号量: %s (初始值: %u)", info->name, initial_value); return THREAD_SUCCESS; } ​ /** * @brief 销毁信号量 * * @param sem 信号量句柄 * @return thread_error_t 错误码 */ thread_error_t thread_sem_destroy(thread_sem_t sem) { if (sem == NULL) { return THREAD_ERROR_PARAM; } sem_info_t* info = (sem_info_t*)sem; /* 销毁信号量 */ int result = sem_destroy(&info->sem); if (result != 0) { base_log(LOG_BASE_LEVEL_WARN, THREAD_MODULE_NAME, "销毁信号量失败: %s", strerror(result)); } base_log(LOG_BASE_LEVEL_DEBUG, THREAD_MODULE_NAME, "销毁信号量: %s", info->name); memory_free(info); return THREAD_SUCCESS; } ​ /** * @brief 等待信号量(P操作) * * @param sem 信号量句柄 * @return thread_error_t 错误码 */ thread_error_t thread_sem_wait(thread_sem_t sem) { if (sem == NULL) { return THREAD_ERROR_PARAM; } sem_info_t* info = (sem_info_t*)sem; int result = sem_wait(&info->sem); if (result != 0) { base_log(LOG_BASE_LEVEL_ERROR, THREAD_MODULE_NAME, "等待信号量失败: %s", strerror(result)); return THREAD_ERROR_SYSTEM; } return THREAD_SUCCESS; } ​ /** * @brief 尝试等待信号量 * * @param sem 信号量句柄 * @return thread_error_t 信号量为0返回THREAD_ERROR_TIMEOUT */ thread_error_t thread_sem_trywait(thread_sem_t sem) { if (sem == NULL) { return THREAD_ERROR_PARAM; } sem_info_t* info = (sem_info_t*)sem; int result = sem_trywait(&info->sem); if (result == -1 && errno == EAGAIN) { return THREAD_ERROR_TIMEOUT; } else if (result != 0) { return THREAD_ERROR_SYSTEM; } return THREAD_SUCCESS; } ​ /** * @brief 带超时的等待信号量 * * @param sem 信号量句柄 * @param timeout_ms 超时时间(毫秒) * @return thread_error_t 超时返回THREAD_ERROR_TIMEOUT */ thread_error_t thread_sem_timedwait(thread_sem_t sem, unsigned int timeout_ms) { if (sem == NULL) { return THREAD_ERROR_PARAM; } sem_info_t* info = (sem_info_t*)sem; struct timespec ts; calculate_abstime(timeout_ms, &ts); int result = sem_timedwait(&info->sem, &ts); if (result == -1 && errno == ETIMEDOUT) { return THREAD_ERROR_TIMEOUT; } else if (result != 0) { return THREAD_ERROR_SYSTEM; } return THREAD_SUCCESS; } ​ /** * @brief 释放信号量(V操作) * * 信号量值加1,唤醒一个等待的线程。 * * @param sem 信号量句柄 * @return thread_error_t 错误码 */ thread_error_t thread_sem_post(thread_sem_t sem) { if (sem == NULL) { return THREAD_ERROR_PARAM; } sem_info_t* info = (sem_info_t*)sem; int result = sem_post(&info->sem); if (result != 0) { base_log(LOG_BASE_LEVEL_ERROR, THREAD_MODULE_NAME, "释放信号量失败: %s", strerror(result)); return THREAD_ERROR_SYSTEM; } return THREAD_SUCCESS; } ​ /** * @brief 获取信号量当前值 * * @param sem 信号量句柄 * @param value 输出参数,接收信号量值 * @return thread_error_t 错误码 */ thread_error_t thread_sem_getvalue(thread_sem_t sem, int* value) { if (sem == NULL || value == NULL) { return THREAD_ERROR_PARAM; } sem_info_t* info = (sem_info_t*)sem; int result = sem_getvalue(&info->sem, value); if (result != 0) { base_log(LOG_BASE_LEVEL_ERROR, THREAD_MODULE_NAME, "获取信号量值失败: %s", strerror(result)); return THREAD_ERROR_SYSTEM; } return THREAD_SUCCESS; } ​

main.c

/** * @file main.c * @brief 主测试程序 */ ​ #include <stdio.h> #include <stdlib.h> #include <signal.h> #include <setjmp.h> #include "../inc/log.h" #include "../inc/memory.h" #include "../inc/thread_linux.h" ​ /* 声明测试函数 */ void test_memory_register_all(void); void test_thread_register_all(void); int test_run_all(void); void test_print_summary(void); ​ /** @brief 全局跳转缓冲区,用于信号处理 */ static sigjmp_buf g_jump_buffer; ​ /** * @brief 信号处理函数 */ static void signal_handler(int sig) { fprintf(stderr, "接收到信号: %d\n", sig); siglongjmp(g_jump_buffer, 1); } ​ /** * @brief 设置信号处理 */ static void setup_signal_handlers(void) { signal(SIGSEGV, signal_handler); /* 段错误 */ signal(SIGABRT, signal_handler); /* 中止 */ signal(SIGINT, signal_handler); /* Ctrl+C */ } ​ /** * @brief 初始化所有模块 */ static bool init_all_modules(void) { printf("初始化所有模块...\n"); /* 初始化日志模块 */ if (!log_init(4096)) { fprintf(stderr, "初始化日志模块失败\n"); return false; } log_set_console_output(true); log_set_level(LOG_BASE_LEVEL_INFO); /* 初始化内存模块 */ if (!memory_init()) { fprintf(stderr, "初始化内存模块失败\n"); log_destroy(); return false; } /* 初始化线程模块 */ if (thread_module_init() != THREAD_SUCCESS) { fprintf(stderr, "初始化线程模块失败\n"); memory_destroy(); log_destroy(); return false; } printf("所有模块初始化成功\n"); return true; } ​ /** * @brief 清理所有模块 */ static void cleanup_all_modules(void) { printf("清理所有模块...\n"); thread_module_destroy(); memory_destroy(); log_destroy(); } ​ /** * @brief 主函数 */ int main(void) { printf("=======================================\n"); printf(" 内存与线程模块测试程序\n"); printf("=======================================\n\n"); setup_signal_handlers(); if (sigsetjmp(g_jump_buffer, 1) != 0) { printf("\n程序异常中断\n"); cleanup_all_modules(); return 1; } if (!init_all_modules()) { return 1; } printf("\n注册测试用例...\n"); test_memory_register_all(); test_thread_register_all(); printf("开始运行测试...\n"); int failed_tests = test_run_all(); test_print_summary(); printf("\n最终内存泄漏检查:\n"); size_t final_leaks = memory_check_leaks(); if (final_leaks > 0) { printf("发现 %zu 处内存泄漏!\n", final_leaks); } else { printf("无内存泄漏\n"); } cleanup_all_modules(); printf("\n=======================================\n"); printf(" 测试程序运行完成\n"); printf("=======================================\n"); return (failed_tests > 0) ? 1 : 0; } ​

test_common.c

/** * @file test_common.c * @brief 测试辅助函数 */ ​ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include "log.h" #include "memory.h" #include "thread_linux.h" ​ #define TEST_MODULE_NAME "TEST" ​ /** * @brief 测试用例结构 */ typedef struct { const char* name; /**< 测试名称 */ bool (*func)(void); /**< 测试函数 */ } test_case_t; ​ /** * @brief 测试上下文结构 */ typedef struct { test_case_t* tests; /**< 测试用例数组 */ size_t count; /**< 测试用例数量 */ size_t passed; /**< 通过的测试数量 */ size_t failed; /**< 失败的测试数量 */ } test_context_t; ​ static test_context_t g_test_context = {0}; ​ /** * @brief 断言宏 */ #define TEST_ASSERT(condition, message) \ do { \ if (!(condition)) { \ base_log(LOG_BASE_LEVEL_ERROR, TEST_MODULE_NAME, \ "断言失败: %s, 文件: %s, 行号: %d", \ message, __FILE__, __LINE__); \ return false; \ } \ } while(0) ​ /** * @brief 断言两个值相等 */ #define TEST_ASSERT_EQ(expected, actual, message) \ TEST_ASSERT((expected) == (actual), \ message " (期望值: " #expected ", 实际值: " #actual ")") ​ /** * @brief 断言指针不为NULL */ #define TEST_ASSERT_NOT_NULL(ptr, message) \ TEST_ASSERT((ptr) != NULL, message " (指针为NULL)") ​ /** * @brief 断言指针为NULL */ #define TEST_ASSERT_NULL(ptr, message) \ TEST_ASSERT((ptr) == NULL, message " (指针不为NULL)") ​ /** * @brief 注册测试用例 * * @param name 测试名称 * @param func 测试函数 */ void test_register(const char* name, bool (*func)(void)) { static test_case_t test_array[100]; static size_t test_count = 0; if (test_count >= sizeof(test_array) / sizeof(test_array[0])) { base_log(LOG_BASE_LEVEL_ERROR, TEST_MODULE_NAME, "测试用例数量超过限制"); return; } test_array[test_count].name = name; test_array[test_count].func = func; test_count++; g_test_context.tests = test_array; g_test_context.count = test_count; } ​ /** * @brief 运行所有测试 * * @return int 失败的测试数量 */ int test_run_all(void) { if (g_test_context.count == 0) { base_log(LOG_BASE_LEVEL_WARN, TEST_MODULE_NAME, "没有注册任何测试用例"); return 0; } printf("\n========== 开始运行测试 ==========\n"); printf("测试用例总数: %zu\n", g_test_context.count); printf("-----------------------------------\n"); clock_t start_time = clock(); for (size_t i = 0; i < g_test_context.count; i++) { test_case_t* test = &g_test_context.tests[i]; printf("运行测试 [%02zu/%02zu]: %-40s ", i + 1, g_test_context.count, test->name); fflush(stdout); bool result = test->func(); if (result) { printf("[PASS]\n"); g_test_context.passed++; } else { printf("[FAIL]\n"); g_test_context.failed++; } } clock_t end_time = clock(); double elapsed = (double)(end_time - start_time) / CLOCKS_PER_SEC; printf("-----------------------------------\n"); printf("测试完成:\n"); printf(" 通过: %zu\n", g_test_context.passed); printf(" 失败: %zu\n", g_test_context.failed); printf(" 耗时: %.3f 秒\n", elapsed); printf("========== 测试运行结束 ==========\n\n"); return g_test_context.failed; } ​ /** * @brief 打印测试摘要 */ void test_print_summary(void) { printf("\n测试结果摘要:\n"); printf(" 总测试用例: %zu\n", g_test_context.count); printf(" 通过: %zu (%.1f%%)\n", g_test_context.passed, (g_test_context.count > 0) ? (double)g_test_context.passed / g_test_context.count * 100 : 0.0); printf(" 失败: %zu (%.1f%%)\n", g_test_context.failed, (g_test_context.count > 0) ? (double)g_test_context.failed / g_test_context.count * 100 : 0.0); if (g_test_context.failed == 0) { printf("\n🎉 所有测试通过!\n"); } else { printf("\n⚠️ 有测试失败,请检查日志。\n"); } } ​

test_memory.c

/** * @file test_memory.c * @brief 内存模块测试 */ ​ #include <stdio.h> #include <stdlib.h> #include <string.h> #include "log.h" #include "memory.h" #include "test_common.h" ​ /** * @brief 测试内存模块初始化 */ static bool test_memory_init(void) { base_log(LOG_BASE_LEVEL_INFO, TEST_MODULE_NAME, "测试内存模块初始化"); bool result = memory_init(); TEST_ASSERT(result, "内存模块初始化失败"); /* 检查初始状态 */ TEST_ASSERT_EQ(0, memory_get_current_total(), "初始内存总量应为0"); TEST_ASSERT_EQ(0, memory_get_peak_total(), "初始峰值内存应为0"); TEST_ASSERT_EQ(0, memory_get_allocation_count(), "初始分配次数应为0"); TEST_ASSERT_EQ(0, memory_get_free_count(), "初始释放次数应为0"); return true; } ​ /** * @brief 测试基本内存分配和释放 */ static bool test_memory_basic_alloc_free(void) { base_log(LOG_BASE_LEVEL_INFO, TEST_MODULE_NAME, "测试基本内存分配和释放"); /* 分配内存 */ void* ptr1 = memory_malloc(100); TEST_ASSERT_NOT_NULL(ptr1, "分配100字节内存失败"); TEST_ASSERT_EQ(100, memory_get_current_total(), "内存总量应为100"); TEST_ASSERT_EQ(100, memory_get_peak_total(), "峰值内存应为100"); TEST_ASSERT_EQ(1, memory_get_allocation_count(), "分配次数应为1"); /* 分配更多内存 */ void* ptr2 = memory_malloc(200); TEST_ASSERT_NOT_NULL(ptr2, "分配200字节内存失败"); TEST_ASSERT_EQ(300, memory_get_current_total(), "内存总量应为300"); TEST_ASSERT_EQ(300, memory_get_peak_total(), "峰值内存应为300"); TEST_ASSERT_EQ(2, memory_get_allocation_count(), "分配次数应为2"); /* 释放内存 */ memory_free(ptr1); TEST_ASSERT_EQ(200, memory_get_current_total(), "释放后内存总量应为200"); TEST_ASSERT_EQ(1, memory_get_free_count(), "释放次数应为1"); memory_free(ptr2); TEST_ASSERT_EQ(0, memory_get_current_total(), "释放后内存总量应为0"); TEST_ASSERT_EQ(2, memory_get_free_count(), "释放次数应为2"); return true; } ​ /** * @brief 测试calloc分配 */ static bool test_memory_calloc(void) { base_log(LOG_BASE_LEVEL_INFO, TEST_MODULE_NAME, "测试calloc内存分配"); /* 分配并清零内存 */ int* array = (int*)memory_calloc(10, sizeof(int)); TEST_ASSERT_NOT_NULL(array, "calloc分配失败"); /* 验证内存被清零 */ for (int i = 0; i < 10; i++) { TEST_ASSERT_EQ(0, array[i], "calloc分配的内存未清零"); } /* 修改内存值 */ for (int i = 0; i < 10; i++) { array[i] = i + 1; } memory_free(array); return true; } ​ /** * @brief 测试realloc重新分配 */ static bool test_memory_realloc(void) { base_log(LOG_BASE_LEVEL_INFO, TEST_MODULE_NAME, "测试realloc内存重新分配"); size_t initial_total = memory_get_current_total(); /* 初始分配 */ int* ptr = (int*)memory_malloc(5 * sizeof(int)); TEST_ASSERT_NOT_NULL(ptr, "初始分配失败"); /* 初始化数据 */ for (int i = 0; i < 5; i++) { ptr[i] = i + 1; } /* 扩大内存 */ ptr = (int*)memory_realloc(ptr, 10 * sizeof(int)); TEST_ASSERT_NOT_NULL(ptr, "realloc扩大内存失败"); /* 验证原有数据 */ for (int i = 0; i < 5; i++) { TEST_ASSERT_EQ(i + 1, ptr[i], "realloc后原有数据丢失"); } /* 缩小内存 */ ptr = (int*)memory_realloc(ptr, 3 * sizeof(int)); TEST_ASSERT_NOT_NULL(ptr, "realloc缩小内存失败"); memory_free(ptr); return true; } ​ /** * @brief 测试重复释放检测 */ static bool test_memory_double_free(void) { base_log(LOG_BASE_LEVEL_INFO, TEST_MODULE_NAME, "测试重复释放检测"); size_t initial_failed_frees = memory_get_failed_free_count(); void* ptr = memory_malloc(50); TEST_ASSERT_NOT_NULL(ptr, "分配内存失败"); /* 第一次释放(正常) */ memory_free(ptr); /* 第二次释放(应该检测到重复释放) */ memory_free(ptr); size_t current_failed_frees = memory_get_failed_free_count(); TEST_ASSERT_EQ(initial_failed_frees + 1, current_failed_frees, "重复释放检测失败"); return true; } ​ /** * @brief 测试内存泄漏检测 */ static bool test_memory_leak_detection(void) { base_log(LOG_BASE_LEVEL_INFO, TEST_MODULE_NAME, "测试内存泄漏检测"); size_t initial_leaks = memory_check_leaks(); /* 故意制造内存泄漏 */ void* leaked_ptr = memory_malloc(100); TEST_ASSERT_NOT_NULL(leaked_ptr, "分配泄漏内存失败"); size_t current_leaks = memory_check_leaks(); TEST_ASSERT_EQ(initial_leaks + 1, current_leaks, "内存泄漏检测失败"); /* 现在修复泄漏 */ memory_free(leaked_ptr); current_leaks = memory_check_leaks(); TEST_ASSERT_EQ(initial_leaks, current_leaks, "修复泄漏后检测失败"); return true; } ​ /** * @brief 测试禁用内存追踪 */ static bool test_memory_disable_tracking(void) { base_log(LOG_BASE_LEVEL_INFO, TEST_MODULE_NAME, "测试禁用内存追踪"); /* 禁用追踪 */ memory_set_tracking(false); TEST_ASSERT(!memory_is_tracking_enabled(), "禁用追踪失败"); /* 分配内存(应该不追踪) */ void* ptr = memory_malloc(100); TEST_ASSERT_NOT_NULL(ptr, "分配内存失败"); size_t alloc_count_before = memory_get_allocation_count(); /* 释放内存 */ memory_free(ptr); size_t alloc_count_after = memory_get_allocation_count(); TEST_ASSERT_EQ(alloc_count_before, alloc_count_after, "禁用追踪时不应计数"); /* 重新启用追踪 */ memory_set_tracking(true); TEST_ASSERT(memory_is_tracking_enabled(), "启用追踪失败"); return true; } ​ /** * @brief 测试大量内存分配 */ static bool test_memory_massive_allocation(void) { base_log(LOG_BASE_LEVEL_INFO, TEST_MODULE_NAME, "测试大量内存分配"); const int NUM_ALLOCATIONS = 100; void* pointers[NUM_ALLOCATIONS]; /* 分配大量内存块 */ for (int i = 0; i < NUM_ALLOCATIONS; i++) { pointers[i] = memory_malloc((i + 1) * 10); TEST_ASSERT_NOT_NULL(pointers[i], "分配内存失败"); } /* 验证分配计数 */ TEST_ASSERT_EQ(NUM_ALLOCATIONS, memory_get_allocation_count() - memory_get_free_count(), "内存块计数错误"); /* 释放所有内存 */ for (int i = 0; i < NUM_ALLOCATIONS; i++) { memory_free(pointers[i]); } /* 验证无泄漏 */ TEST_ASSERT_EQ(0, memory_check_leaks(), "内存泄漏检测失败"); return true; } ​ /** * @brief 测试内存统计信息 */ static bool test_memory_statistics(void) { base_log(LOG_BASE_LEVEL_INFO, TEST_MODULE_NAME, "测试内存统计信息"); size_t initial_peak = memory_get_peak_total(); /* 分配内存 */ void* ptr1 = memory_malloc(1000); void* ptr2 = memory_malloc(500); /* 验证峰值更新 */ size_t current_peak = memory_get_peak_total(); TEST_ASSERT(current_peak >= 1500, "峰值内存统计错误"); /* 释放部分内存 */ memory_free(ptr1); /* 峰值应该保持不变 */ TEST_ASSERT_EQ(current_peak, memory_get_peak_total(), "释放内存后峰值不应改变"); /* 分配更多内存(超过当前峰值) */ void* ptr3 = memory_malloc(2000); TEST_ASSERT(memory_get_peak_total() >= 2500, "新峰值应更新"); /* 清理 */ memory_free(ptr2); memory_free(ptr3); return true; } ​ /** * @brief 注册所有内存测试用例 */ void test_memory_register_all(void) { test_register("内存模块初始化", test_memory_init); test_register("基本分配释放", test_memory_basic_alloc_free); test_register("calloc分配", test_memory_calloc); test_register("realloc重分配", test_memory_realloc); test_register("重复释放检测", test_memory_double_free); test_register("内存泄漏检测", test_memory_leak_detection); test_register("禁用内存追踪", test_memory_disable_tracking); test_register("大量内存分配", test_memory_massive_allocation); test_register("内存统计信息", test_memory_statistics); } ​

test_thread.c

/** * @file test_thread.c * @brief 线程模块测试 */ ​ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/time.h> #include <errno.h> #include <semaphore.h> #include <time.h> #include <pthread.h> ​ #include "log.h" #include "memory.h" #include "thread_linux.h" #include "test_common.h" ​ /** * @brief 测试线程数据 */ typedef struct { int value; char message[64]; bool completed; } test_thread_data_t; ​ static unsigned long long get_current_time_ms(void) { struct timespec ts; /* 使用单调时钟,不受系统时间调整影响 */ if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) { /* 如果失败,使用实时时钟作为备用 */ clock_gettime(CLOCK_REALTIME, &ts); } return (unsigned long long)ts.tv_sec * 1000 + ts.tv_nsec / 1000000; } ​ /** * @brief 简单线程函数 */ static void* simple_thread_func(void* arg) { test_thread_data_t* data = (test_thread_data_t*)arg; base_log(LOG_BASE_LEVEL_DEBUG, TEST_MODULE_NAME, "线程开始执行,参数值: %d, 消息: %s", >第三部分 Makefile
# 项目名称 PROJECT = thread_memory_test COMMON_TEST = test_common LIB_NAME = common LIB_STATIC = lib$(LIB_NAME).a LIB_SHARED = lib$(LIB_NAME).so ​ # 编译器设置 CC = gcc CFLAGS = -Wall -Wextra -g -O0 -std=c99 -pthread -fPIC CFLAGS += -D_GNU_SOURCE # 启用GNU扩展(如果需要) ​ # 目录设置 BASE_DIR = . INCLUDE_DIR = $(BASE_DIR)/inc SRC_DIR = $(BASE_DIR)/src TEST_DIR = $(BASE_DIR)/test BUILD_DIR = ../build LIB_DIR = ../lib LIB_INCLUDE_DIR = $(LIB_DIR)/include ​ # 源文件 COMMON_SRC = $(SRC_DIR)/common.c LOG_SRC = $(SRC_DIR)/log.c MEMORY_SRC = $(SRC_DIR)/memory.c THREAD_SRC = $(SRC_DIR)/thread_linux.c ​ TEST_SRCS = $(TEST_DIR)/main.c \ $(TEST_DIR)/test_memory.c \ $(TEST_DIR)/test_thread.c \ $(TEST_DIR)/test_common.c ​ COMMON_TEST_SRC = $(TEST_DIR)/test_out.c ​ # 目标文件 COMMON_OBJ = $(BUILD_DIR)/common.o LOG_OBJ = $(BUILD_DIR)/log.o MEMORY_OBJ = $(BUILD_DIR)/memory.o THREAD_OBJ = $(BUILD_DIR)/thread_linux.o ​ TEST_OBJS = $(BUILD_DIR)/main.o \ $(BUILD_DIR)/test_memory.o \ $(BUILD_DIR)/test_thread.o \ $(BUILD_DIR)/test_common.o ​ COMMON_TEST_OBJ = $(BUILD_DIR)/test_out.o ​ # 库对象文件列表 LIB_OBJS = $(COMMON_OBJ) $(LOG_OBJ) $(MEMORY_OBJ) $(THREAD_OBJ) ​ # 最终可执行文件 TARGET = $(BUILD_DIR)/$(PROJECT) COMMON_TARGET = $(BUILD_DIR)/$(COMMON_TEST) ​ # 包含路径 INC_FLAGS = -I$(INCLUDE_DIR) ​ # 默认目标 all: $(BUILD_DIR) libs tests ​ # 创建构建目录 $(BUILD_DIR): mkdir -p $(BUILD_DIR) ​ # 创建库目录 $(LIB_DIR): mkdir -p $(LIB_DIR) mkdir -p $(LIB_INCLUDE_DIR) ​ # ==================== 库构建 ==================== ​ # 构建静态库 static: $(LIB_DIR) $(LIB_OBJS) ar rcs $(LIB_DIR)/$(LIB_STATIC) $(LIB_OBJS) @echo "创建静态库: $(LIB_DIR)/$(LIB_STATIC)" ​ # 构建动态库 shared: $(LIB_DIR) $(LIB_OBJS) $(CC) -shared -o $(LIB_DIR)/$(LIB_SHARED) $(LIB_OBJS) -pthread -lm @echo "创建动态库: $(LIB_DIR)/$(LIB_SHARED)" ​ # 构建所有库 libs: static shared @echo "复制头文件到库目录..." @mkdir -p "$(LIB_INCLUDE_DIR)" 2>/dev/null || true @cp $(INCLUDE_DIR)/*.h "$(LIB_INCLUDE_DIR)/" 2>/dev/null || true @echo "库构建完成" @echo "静态库: $(LIB_DIR)/$(LIB_STATIC)" @echo "动态库: $(LIB_DIR)/$(LIB_SHARED)" @echo "头文件: $(LIB_INCLUDE_DIR)/" ​ # ==================== 测试程序构建 ==================== ​ # 构建原测试程序 tests: $(TARGET) $(COMMON_TARGET) ​ # 链接生成原测试程序 $(TARGET): $(LIB_OBJS) $(TEST_OBJS) $(CC) $(CFLAGS) $(INC_FLAGS) -o $@ $^ -pthread -lm ​ # 链接生成common测试程序 $(COMMON_TARGET): $(LIB_OBJS) $(COMMON_TEST_OBJ) $(CC) $(CFLAGS) $(INC_FLAGS) -o $@ $^ -pthread -lm ​ # ==================== 编译规则 ==================== ​ # 编译common模块 $(BUILD_DIR)/common.o: $(COMMON_SRC) $(INCLUDE_DIR)/common.h $(INCLUDE_DIR)/log.h $(INCLUDE_DIR)/memory.h $(INCLUDE_DIR)/thread_linux.h $(CC) $(CFLAGS) $(INC_FLAGS) -c $< -o $@ ​ # 编译日志模块 $(BUILD_DIR)/log.o: $(LOG_SRC) $(INCLUDE_DIR)/log.h $(CC) $(CFLAGS) $(INC_FLAGS) -c $< -o $@ ​ # 编译内存模块 $(BUILD_DIR)/memory.o: $(MEMORY_SRC) $(INCLUDE_DIR)/memory.h $(INCLUDE_DIR)/log.h $(CC) $(CFLAGS) $(INC_FLAGS) -c $< -o $@ ​ # 编译线程模块 $(BUILD_DIR)/thread_linux.o: $(THREAD_SRC) $(INCLUDE_DIR)/thread_linux.h $(INCLUDE_DIR)/log.h $(INCLUDE_DIR)/memory.h $(CC) $(CFLAGS) $(INC_FLAGS) -c $< -o $@ ​ # 编译 test_common.c(需要 common.h 依赖) $(BUILD_DIR)/test_common.o: $(TEST_DIR)/test_common.c $(INCLUDE_DIR)/common.h $(CC) $(CFLAGS) $(INC_FLAGS) -c $< -o $@ # 编译测试文件 $(BUILD_DIR)/%.o: $(TEST_DIR)/%.c $(CC) $(CFLAGS) $(INC_FLAGS) -c $< -o $@ ​ # ==================== 清理 ==================== ​ clean: rm -rf $(BUILD_DIR)/* rm -rf $(LIB_DIR)/* ​ cleanlib: rm -rf $(LIB_DIR)/* ​ cleantest: rm -rf $(BUILD_DIR)/* ​ # ==================== 运行测试 ==================== ​ # 运行原测试 run: $(TARGET) ./$(TARGET) ​ # 运行common测试 runcommon: $(COMMON_TARGET) ./$(COMMON_TARGET) ​ # 调试运行 debug: $(TARGET) gdb -q ./$(TARGET) ​ # 检查内存泄漏(使用valgrind) valgrind: $(TARGET) valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes ./$(TARGET) ​ valgrind-common: $(COMMON_TARGET) valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes ./$(COMMON_TARGET) ​ # ==================== 其他命令 ==================== ​ # 安装库到系统目录(需要sudo) install: libs @echo "安装库到系统目录..." cp $(LIB_DIR)/$(LIB_STATIC) /usr/local/lib/ cp $(LIB_DIR)/$(LIB_SHARED) /usr/local/lib/ ldconfig cp $(LIB_INCLUDE_DIR)/*.h /usr/local/include/ @echo "安装完成" ​ # 卸载库 uninstall: @echo "卸载库..." rm -f /usr/local/lib/$(LIB_STATIC) rm -f /usr/local/lib/$(LIB_SHARED) rm -f /usr/local/include/common.h rm -f /usr/local/include/log.h rm -f /usr/local/include/memory.h rm -f /usr/local/include/thread_linux.h ldconfig @echo "卸载完成" ​ # 显示项目结构 tree: @echo "项目结构:" @echo "tools_file/" @echo "├── base/" @echo "│ ├── inc/" @for file in $(INCLUDE_DIR)/*.h; do \ if [ -f "$$file" ]; then \ echo "│ │ ├── $$(basename $$file)"; \ fi; \ done @echo "│ ├── src/" @for file in $(SRC_DIR)/*.c; do \ if [ -f "$$file" ]; then \ echo "│ │ ├── $$(basename $$file)"; \ fi; \ done @echo "│ ├── test/" @for file in $(TEST_DIR)/*.c; do \ if [ -f "$$file" ]; then \ echo "│ │ ├── $$(basename $$file)"; \ fi; \ done @for file in $(TEST_DIR)/*.h; do \ if [ -f "$$file" ]; then \ echo "│ │ ├── $$(basename $$file)"; \ fi; \ done @echo "│ └── Makefile" @echo "├── lib/" @echo "│ ├── libcommon.a" @echo "│ ├── libcommon.so" @echo "│ └── include/" @for file in $(INCLUDE_DIR)/*.h; do \ if [ -f "$$file" ]; then \ echo "│ ├── $$(basename $$file)"; \ fi; \ done @echo "└── build/" @echo " ├── *.o" @echo " ├── test_common" @echo " └── thread_memory_test" ​ # 显示帮助信息 help: @echo "可用命令:" @echo " make all - 构建所有(库和测试程序)" @echo " make libs - 构建静态库和动态库" @echo " make static - 仅构建静态库" @echo " make shared - 仅构建动态库" @echo " make tests - 构建测试程序" @echo " make run - 运行原测试程序" @echo " make runcommon - 运行common测试程序" @echo " make clean - 清理所有构建文件" @echo " make cleanlib - 仅清理库文件" @echo " make cleantest - 仅清理测试程序" @echo " make install - 安装库到系统目录(需要sudo)" @echo " make uninstall - 卸载库" @echo " make tree - 显示项目结构" @echo " make help - 显示此帮助信息" ​ .PHONY: all libs static shared tests run runcommon debug valgrind valgrind-common clean cleanlib cleantest install uninstall tree help ​
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/23 23:42:45

2026年,你希望公司更离不开你,还是你更离不开公司?

上个月底&#xff0c;在南山科技园一家咖啡馆&#xff0c;我碰见老周—— 他做工业传感器的&#xff0c;厂在龙华观澜&#xff0c;二十来号人&#xff0c;年营收3000万左右。 他眼圈发黑&#xff0c;手抖着搅咖啡&#xff1a; “昨晚又通宵改PPT&#xff0c;给投资人看明年规划…

作者头像 李华
网站建设 2026/2/24 10:17:00

YOLOv10优化:注意力魔改 | 新颖的卷积轴向注意力和谱空间注意力助力涨点,适用高分辨率场景,2025.12

💡💡💡本文改进内容: 卷积轴向注意力模块:与标准轴向注意力不同,CAAM在沿高度和宽度方向进行方向性注意力之前,加入了卷积投影。这减少了冗余和计算开销,产生了一种适合高分辨率场景的、具有上下文感知且高效的表征。 谱空间注意力模块:该模块联合重新加权光谱通道…

作者头像 李华
网站建设 2026/2/23 19:16:40

35、gawk调试器命令全解析

gawk调试器命令全解析 在使用gawk进行编程时,调试是一个必不可少的环节。下面将详细介绍gawk调试器的相关命令及使用方法。 调试实例引入 首先来看一个调试实例。代码如下: alast["4"] = "wonderful" alast["5"] = "program!"接…

作者头像 李华
网站建设 2026/2/23 0:51:44

41、gawk扩展功能全解析

gawk扩展功能全解析 1. 代码加载与初始化 在编写gawk扩展时,需要完成一系列的代码加载与初始化工作。首先是更新错误号并返回结果的代码: update_ERRNO_int(errno); return make_number(ret, result);还有通过 fill_stat_array() 函数完成繁琐工作,完成后返回其结果:…

作者头像 李华
网站建设 2026/2/22 21:25:09

Java Web 核心全解析

Java Web 是基于 Java 技术栈构建 Web 应用的开发体系&#xff0c;涵盖前端交互、后端逻辑、服务器部署、数据存储等全链路&#xff0c;是企业级应用&#xff08;电商、金融、政务等&#xff09;的主流开发方案&#xff0c;以下从核心架构、技术栈、开发流程、主流框架等维度拆…

作者头像 李华
网站建设 2026/2/24 18:08:27

7、远程服务安全攻防全解析

远程服务安全攻防全解析 一、服务识别与基础脚本 1.1 脚本执行与服务识别 在网络安全的探索中,我们常常需要借助特定的脚本来进行服务识别。例如,有一个名为 wrapper - grab.bash 的脚本,它能够针对 hosts.txt 文件中列出的主机执行原始脚本 grab.bash 。 hosts.t…

作者头像 李华