博客
关于我
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/

你可能感兴趣的文章
mysqli
查看>>
MySQLIntegrityConstraintViolationException异常处理
查看>>
mysqlreport分析工具详解
查看>>
MySQLSyntaxErrorException: Unknown error 1146和SQLSyntaxErrorException: Unknown error 1146
查看>>
Mysql_Postgresql中_geometry数据操作_st_astext_GeomFromEWKT函数_在java中转换geometry的16进制数据---PostgreSQL工作笔记007
查看>>
mysql_real_connect 参数注意
查看>>
mysql_secure_installation初始化数据库报Access denied
查看>>
MySQL_西安11月销售昨日未上架的产品_20161212
查看>>
Mysql——深入浅出InnoDB底层原理
查看>>
MySQL“被动”性能优化汇总
查看>>
MySQL、HBase 和 Elasticsearch:特点与区别详解
查看>>
MySQL、Redis高频面试题汇总
查看>>
MYSQL、SQL Server、Oracle数据库排序空值null问题及其解决办法
查看>>
mysql一个字段为空时使用另一个字段排序
查看>>
MySQL一个表A中多个字段关联了表B的ID,如何关联查询?
查看>>
MYSQL一直显示正在启动
查看>>
MySQL一站到底!华为首发MySQL进阶宝典,基础+优化+源码+架构+实战五飞
查看>>
MySQL万字总结!超详细!
查看>>
Mysql下载以及安装(新手入门,超详细)
查看>>
MySQL不会性能调优?看看这份清华架构师编写的MySQL性能优化手册吧
查看>>