Linux应用层开发--线程池介绍
Glib 线程池
1. 线程池简介
线程池是一种管理和重用多个线程的设计模式:
- 避免频繁创建/销毁线程的开销。
- 提高性能与资源利用率。
- 任务提交后,由线程池内的线程自动执行,任务执行完线程不会退出,而是继续等待下一个任务。
2. Glib 库简介
- Glib 是 GNOME 项目的基础库,提供数据结构、工具函数、线程支持等功能。
- 官网文档:https://docs.gtk.org/glib/
- 安装开发包:
sudo apt-get update
sudo apt-get install libglib2.0-dev
3. Glib 线程池工作流程
-
创建线程池
-
指定任务函数
func
(所有任务都调用它)。 -
设置线程池大小、是否独占线程。
-
-
任务入队
- 通过
g_thread_pool_push
将任务数据放入任务队列。
- 通过
-
执行任务
- 线程池线程取出任务数据 → 调用
func
→ 执行完成后继续等待下一个任务。
- 线程池线程取出任务数据 → 调用
-
释放线程池
- 等任务全部完成或立即销毁(可配置)。
4. 常用数据类型(编程时会遇到)
- GFunc:任务函数类型
typedef void (*GFunc)(gpointer data, gpointer user_data);
// data: 每个任务单独的数据
// user_data: 创建线程池时传入的共享数据
-
gpointer:
void*
类型指针 -
gint:
int
类型 -
gboolean:布尔值(TRUE=1, FALSE=0)
-
GError:错误信息结构体(包含错误域、错误码、错误描述)
-
GThreadPool:线程池结构体(包含任务函数、共享数据、是否独占线程等)
5. 常用函数(写代码时直接用)
1)创建线程池
GThreadPool* g_thread_pool_new(GFunc func, // 任务函数gpointer user_data, // 共享数据(可为NULL)gint max_threads, // 最大线程数(-1为无限制)gboolean exclusive, // TRUE 独占线程, FALSE 共享线程GError **error // 错误信息(可为NULL)
);
2)添加任务
gboolean g_thread_pool_push(GThreadPool *pool, // 线程池实例gpointer data, // 每个任务独有的数据GError **error // 错误信息(可为NULL)
);
3)释放线程池
void g_thread_pool_free(GThreadPool *pool,gboolean immediate, // TRUE 立即销毁,不执行剩余任务gboolean wait_ // TRUE 等所有任务执行完才返回
);
6. 编程步骤(写代码条理)
① 编写任务函数
void task_func(gpointer data, gpointer user_data) {int task_num = *(int*)data; // 转换任务数据free(data); // 释放任务数据内存printf("Executing task %d...\n", task_num);sleep(1); // 模拟任务耗时printf("Task %d completed\n", task_num);
}
② 创建线程池
GThreadPool *pool = g_thread_pool_new(task_func, // 任务函数NULL, // 共享数据(此处无)5, // 最大线程数TRUE, // 独占线程NULL // 忽略错误
);
③ 提交任务
for (int i = 0; i < 10; i++) {int *num = malloc(sizeof(int));*num = i + 1;g_thread_pool_push(pool, num, NULL);
}
④ 等待任务完成并释放资源
g_thread_pool_free(pool, FALSE, TRUE);
printf("All tasks completed\n");
7. 代码编写流程图
┌─────────────────────┐│ ① 编写任务函数 ││---------------------││ void task_func(...) ││ - 解析任务数据 ││ - 执行任务逻辑 ││ - 释放内存 │└─────────┬───────────┘│▼┌─────────────────────┐│ ② 创建线程池 ││---------------------││ g_thread_pool_new() ││ - 任务函数指针 ││ - 共享数据(NULL) ││ - 最大线程数 ││ - 独占/共享模式 │└─────────┬───────────┘│▼┌─────────────────────┐│ ③ 提交任务 ││---------------------││ 循环 malloc 数据 ││ g_thread_pool_push()││ - 每个任务独立数据││ - 加入任务队列 │└─────────┬───────────┘│▼┌─────────────────────┐│ ④ 等待并释放资源 ││---------------------││ g_thread_pool_free()││ - immediate=FALSE ││ - wait_=TRUE ││ 等所有任务完成后返回 │└─────────────────────┘
8. pkg-config 作用
- 获取编译和链接所需的参数,避免手动写路径和库名:
pkg-config --cflags glib-2.0 # 输出头文件路径
pkg-config --libs glib-2.0 # 输出链接库参数
- 合并使用:
pkg-config --cflags --libs glib-2.0
等价于编译时手动加:
-I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -lglib-2.0