博客
关于我
5_04_GLib库入门与实践_线程池
阅读量:797 次
发布时间:2019-03-25

本文共 6623 字,大约阅读时间需要 22 分钟。

GLib线程池技术文档

简介

线程池是一种优化多线程应用程序性能的技术。在多线程编程中,频繁创建和销毁线程会导致系统资源消耗增加。通过在后续任务启动前复用之前创建的线程,线程池能够显著降低资源浪费。GLib线程池提供了一套功能丰富的API,支持任务_submission、线程管理以及任务排序等操作。

数据结构

线程池的内部数据结构由以下三个成员变量组成:

struct GThreadPool {
GFunc func; // 线程执行的函数指针
gpointer user_data; // 线程任务的用户数据
gboolean exclusive; // 线程池是否为独占线程池
};

函数列表

线程池提供了多个函数来管理线程池:

  • GThreadPool * g_thread_pool_new()
  • gboolean g_thread_pool_push()
  • gboolean g_thread_pool_set_max_threads()
  • gint g_thread_pool_get_max_threads()
  • guint g_thread_pool_get_num_threads()
  • guint g_thread_pool_unprocessed()
  • void g_thread_pool_free()
  • void g_thread_pool_set_max_unused_threads()
  • gint g_thread_pool_get_max_unused_threads()
  • guint g_thread_pool_get_num_unused_threads()
  • void g_thread_pool_stop_unused_threads()
  • void g_thread_pool_set_sort_function()
  • guint g_thread_pool_get_max_idle_time()
  • gboolean g_thread_pool_move_to_front()

函数分类

创建

  • GThreadPool * g_thread_pool_new()

销毁

  • void g_thread_pool_free()

发送数据

  • gboolean g_thread_pool_push()

查询

  • gint g_thread_pool_get_max_threads()
  • guint g_thread_pool_get_num_threads()
  • gint g_thread_pool_get_max_unused_threads()
  • guint g_thread_pool_get_num_unused_threads()
  • guint g_thread_pool_get_max_idle_time()
  • guint g_thread_pool_unprocessed()

设置

  • gboolean g_thread_pool_set_max_threads()
  • void g_thread_pool_set_max_unused_threads()
  • void g_thread_pool_set_max_idle_time()

任务优先执行

  • gboolean g_thread_pool_move_to_front()

任务排序

  • void g_thread_pool_set_sort_function()

其他

  • void g_thread_pool_stop_unused_threads()

函数说明及综合演示

向线程池发送任务

使用线程池的步骤如下示例:

#include 
static void test_thread_pool_func(gpointer data, gpointer user_data) {
g_print("get data: %d ", GPOINTER_TO_INT(data));
}
void test_thread_pool_push(void) {
GThreadPool *pool = NULL;
GError *error = NULL;
potv *pool = g_thread_pool_new(test_thread_pool_func, NULL, 4, FALSE, &error);
if (!pool) {
g_error(" unable to create thread pool");
return;
}
if (g_thread_pool_push(pool, GINT_TO_POINTER(99))) {
g_print("successfull pushed task");
} else {
g_print(" failed to push task");
}
g_thread_pool_free(pool, TRUE, TRUE);
}
int main(int argc, char **argv) {
test_thread_pool_push();
return 0;
}

运行结果显示任务已成功提交到线程池执行。

不同线程执行不同的函数

编写一个任务处理函数,使线程池能够处理多种任务:

#include 
typedef int (*foobar_method)(int a, int b);
typedef struct {
int foo;
int bar;
foobar_method func;
} foobar_t;
static int test_foobar_add(int a, int b) {
return a + b;
}
static int test_foobar_multi(int a, int b) {
return a * b;
}
static void test_thread_pool_func(gpointer data, gpointer user_data) {
foobar_t *foobar = (foobar_t *)data;
if (!foobar) {
return;
}
int ret_val = foobar->func(foobar->foo, foobar->bar);
g_print("ret_val: %d", ret_val);
g_free(foobar);
}
gpointer test_thread_func(gpointer data) {
foobar_t *foobar = g_new(foobar_t, 1);
foobar->foo = 2;
foobar->bar = 3;
foobar->func = test_foobar_add;
g_thread_pool_push(data, (gpointer)foobar);
// 重置数据并设置不同的函数
foobar->foo = 2;
foobar->bar = 3;
foobar->func = test_foobar_multi;
g_thread_pool_push(data, (gpointer)foobar);
g_free(foobar);
return NULL;
}
void test_thread_pool(void) {
GError *error = NULL;
GThread *thd = NULL;
GThreadPool *pool = g_thread_pool_new(test_thread_pool_func, NULL, 4, True, &error);
if (!pool) {
g_error(" unable to create thread pool");
return;
}
thd = g_thread_new("test-thread", test_thread_func, pool);
g_thread_join(thd);
g_thread_pool_free(pool, TRUE, TRUE);
}
int main(int argc, char **argv) {
test_thread_pool();
return 0;
}

运行结果表明不同的函数已经在不同的线程中正确执行。

设置线程池最大线程数

使用g_thread_pool_set_max_threads可以设置线程池的最大线程数:

#include 
static void test_thread_pool_func(gpointer data, gpointer user_data) {
g_print("tid %ld: get data: %d ", (longlong)pthread_self(), GPOINTER_TO_INT(data));
sleep(1);
if (GPOINTER_TO_INT(data) == TEST_THREAD_POOL_FIN) {
g_print("theadpool free ");
g_thread_pool_free(g_pool, TRUE, TRUE);
}
}
gpointer test_thread_func(gpointer data) {
GThreadPool *pool = (GThreadPool *)data;
if (!pool) return NULL;
// 设置最大线程数为0以测试设置
g_thread_pool_set_max_threads(pool, 0, NULL);
sleep(1);
// 重新设置为4
g_thread_pool_set_max_threads(pool, 4, NULL);
// 发送多个任务
g_thread_pool_push(pool, GINT_TO_POINTER(99));
g_thread_pool_push(pool, GINT_TO_POINTER(100));
sleep(1);
return NULL;
}
void test_thread_pool(void) {
GError *error = NULL;
GThread *thd = NULL;
GThreadPool *pool = g_thread_pool_new(test_thread_pool_func, NULL, 4, TRUE, &error);
sleep(1);
thd = g_thread_new("test-thread", test_thread_func, pool);
sleep(1);
g_thread_join(thd);
g_thread_pool_free(pool, TRUE, TRUE);
}
int main(int argc, char **argv) {
test_thread_pool();
return 0;
}

运行结果表明线程池在成功设置最大线程数后,能够正确管理线程数。

任务排序

使用g_thread_pool_set_sort_function可以自定义任务排序:

#include 
static int _test_thread_int_cmp_func(gconstpointer a, gconstpointer b, gpointer user_data) {
return GPOINTER_TO_INT(a) - GPOINTER_TO_INT(b);
}
static void test_thread_pool_func(gpointer data, gpointer user_data) {
g_print("tid %ld: get data: %d ", (longlong)pthread_self(), GPOINTER_TO_INT(data));
sleep(1);
if (GPOINTER_TO_INT(data) == TEST_THREAD_POOL_FIN) {
g_print("theadpool free ");
g_thread_pool_free(g_pool, TRUE, TRUE);
}
}
gpointer test_thread_func(gpointer data) {
GThreadPool *pool = (GThreadPool *)data;
if (!pool) return NULL;
// 设置线程池为1个线程
g_thread_pool_set_max_threads(pool, 1, NULL);
sleep(1);
// 不同的任务使用相同线程
g_thread_pool_set_sort_function(pool, _test_thread_int_cmp_func, NULL);
// 发送多个任务
g_thread_pool_push(pool, GINT_TO_POINTER(99));
g_thread_pool_push(pool, GINT_TO_POINTER(120));
g_thread_pool_push(pool, GINT_TO_POINTER(101));
g_thread_pool_push(pool, GINT_TO_POINTER(106));
g_thread_pool_push(pool, GINT_TO_POINTER(203));
g_thread_pool_push(pool, GINT_TO_POINTER(104));
return NULL;
}
void test_thread_pool(void) {
GError *error = NULL;
GThread *thd = NULL;
GThreadPool *pool = g_thread_pool_new(test_thread_pool_func, NULL, 1, TRUE, &error);
sleep(1);
thd = g_thread_new("test-thread", test_thread_func, pool);
sleep(1);
g_thread_join(thd);
g_thread_pool_free(pool, TRUE, TRUE);
}
int main(int argc, char **argv) {
test_thread_pool();
return 0;
}

运行结果表明排序函数能够按照指定的顺序执行任务。

结论

GLib线程池为开发人员提供了一个高效且灵活的工具来管理多线程任务。通过合理设置线程池参数,可以优化应用程序的性能表现,同时通过自定义排序函数实现任务执行订单的需求。

转载地址:http://ejsuk.baihongyu.com/

你可能感兴趣的文章
mysql5.7安装
查看>>
mysql5.7性能调优my.ini
查看>>
MySQL5.7新增Performance Schema表
查看>>
Mysql5.7深入学习 1.MySQL 5.7 中的新增功能
查看>>
Webpack 之 basic chunk graph
查看>>
Mysql5.7版本单机版my.cnf配置文件
查看>>
mysql5.7的安装和Navicat的安装
查看>>
mysql5.7示例数据库_Linux MySQL5.7多实例数据库配置
查看>>
Mysql8 数据库安装及主从配置 | Spring Cloud 2
查看>>
mysql8 配置文件配置group 问题 sql语句group不能使用报错解决 mysql8.X版本的my.cnf配置文件 my.cnf文件 能够使用的my.cnf配置文件
查看>>
MySQL8.0.29启动报错Different lower_case_table_names settings for server (‘0‘) and data dictionary (‘1‘)
查看>>
MYSQL8.0以上忘记root密码
查看>>
Mysql8.0以上重置初始密码的方法
查看>>
mysql8.0新特性-自增变量的持久化
查看>>
Mysql8.0注意url变更写法
查看>>
Mysql8.0的特性
查看>>
MySQL8修改密码报错ERROR 1819 (HY000): Your password does not satisfy the current policy requirements
查看>>
MySQL8修改密码的方法
查看>>
Mysql8在Centos上安装后忘记root密码如何重新设置
查看>>
Mysql8在Windows上离线安装时忘记root密码
查看>>