我是靠谱客的博主 飞快树叶,最近开发中收集的这篇文章主要介绍5_04_GLib库入门与实践_线程池,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

简介

线程池是在多线程编程时经常用到的技术。在进行多线程任务处理时,如果线程频繁创建和销毁,将会使系统开销变大,在这种情况下,上一个任务执行完后不销毁之前创建的线程,后续任务重用该线程,将会大大减小开销。为了管理这些创建之后不再销毁的线程,便有了线程池的概念。
GLib的线程池除了提供一般的线程池函数外,还提供了诸如获取当前运行的线程数量、获取未处理的任务数量、获取或设置线程池的最大线程数量、获取未使用的线程数量、设置未使用的最大线程数量、停止所有目前未使用的线程,但经过实际测试,这里面有些功能并未生效。

数据结构

线程池有三个成员变量。
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 ()
void
g_thread_pool_set_max_idle_time ()
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 ()
// (不可用)获取线程池最大不可用线程数量,作用未知,此接口的值所有GThreadPool线程池共用
gint
g_thread_pool_get_max_unused_threads ()
// (不可用)线程处理完本任务要处理下一个任务前的暂停时间,经测试也不生效
guint
g_thread_pool_get_max_idle_time ()
//返回线程池中还没有处理的任务队列中的任务个数
guint
g_thread_pool_unprocessed ()

设置

// 设置线程池的最大线程个数
// 如果线程池是独占的(g_thread_pool_new的exclusive参数为TRUE),则不允许设置为-1
// 如果线程池是非独占的,此值设置为-1表明线程池最大线程个数不限制。
// 如果此值设置为0,则线程池停止工作,直到其再次被设置为一个非0值,线程池重新工作。
gboolean
g_thread_pool_set_max_threads ()
// (不可用)设置最大不可用线程数量,默认值为2
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 ()

函数功能说明及综合演示

向线程池发送任务

创建一个线程池,并通过g_thread_pool_push函数向线程池发送任务,使其执行。
示例代码如下:
源码见glib_examplesglib_threadpoolglib_threadpool_push

#include <glib.h>
static void test_thread_pool_func(gpointer data, gpointer user_data)
{
g_print("get data: %d n", GPOINTER_TO_INT(data));
}
void test_thread_pool_push(void)
{
GThreadPool *pool = NULL;
GError *error = NULL;
gint max_threads = 4;
pool = g_thread_pool_new(test_thread_pool_func, NULL, max_threads, FALSE, &error);
g_thread_pool_push(pool, GINT_TO_POINTER(99), &error);
g_usleep(100*1000);
g_thread_pool_free(pool, TRUE, TRUE);
}
gint main(gint argc, gchar **argv)
{
test_thread_pool_push();
}

运行结果:

[root@centos7_6 build]#glib_threadpool_push
get data: 99

下面程序演示将g_thread_pool_push函数放到独立的线程中。
源码见glib_examplesglib_threadpoolglib_theadpool_push2

#include <glib.h>
#include <pthread.h>
#define TEST_THREAD_POOL_FIN 9999
GThreadPool *g_pool = NULL;
static void test_thread_pool_func(gpointer data, gpointer user_data)
{
g_print("tid %ld: get data: %d n", (glong)pthread_self(), GPOINTER_TO_INT(data));
g_usleep(50*1000);
if(TEST_THREAD_POOL_FIN == GPOINTER_TO_INT(data)) {
g_print("theadpool free n");
g_thread_pool_free(g_pool, TRUE, TRUE);
}
}
gpointer test_thread_func(gpointer data)
{
GThreadPool *pool = (GThreadPool *)data;
g_thread_pool_push(pool, GINT_TO_POINTER(99), NULL);
g_thread_pool_push(pool, GINT_TO_POINTER(100), NULL);
g_thread_pool_push(pool, GINT_TO_POINTER(101), NULL);
g_thread_pool_push(pool, GINT_TO_POINTER(102), NULL);
g_thread_pool_push(pool, GINT_TO_POINTER(103), NULL);
g_thread_pool_push(pool, GINT_TO_POINTER(TEST_THREAD_POOL_FIN), NULL);
return NULL;
}
void test_thread_pool(void)
{
guint num = 0;
GError *error = NULL;
gint max_threads = 4;
GThread *thd = NULL;
g_pool = g_thread_pool_new(test_thread_pool_func, NULL, max_threads, TRUE, &error);
thd = g_thread_new("thd", test_thread_func, g_pool);
g_usleep(500*1000);
g_thread_join(thd);
}
gint main(gint argc, gchar **argv)
{
test_thread_pool();
}

运行结果:

[root@centos7_6 build]# ./glib_theadpool_push2 
tid 140058740213504: get data: 99
tid 140058756998912: get data: 100
tid 140058615084800: get data: 101
tid 140058748606208: get data: 102
tid 140058740213504: get data: 103
tid 140058756998912: get data: 9999
theadpool free

不同线程执行不同的函数

在一些场景下,希望g_thread_pool_push函数向线程池发送的数据,可以被不同的线程执行函数所执行。
下面就演示这一功能。
先来看一个错误的例子。
源码见glib_examplesglib_threadpoolglib_theadpool_diff_func_err

#include <glib.h>
#include <pthread.h>
typedef int (*foobar_method)(gint a, gint b);
typedef struct foobar_tag {
gint foo;
gint bar;
foobar_method func;
}foobar_t;
static gint test_foobar_add(gint a, gint b)
{
return a + b;
}
static gint test_foobar_multi(gint a, gint b)
{
return a * b;
}
static void test_thread_pool_func(gpointer data, gpointer user_data)
{
gint ret_val = 0;
foobar_t *foobar = NULL;
foobar = g_new0(foobar_t, 1);
if(NULL == foobar) {
return;
}
foobar->foo = ((foobar_t *)(data))->foo;
foobar->bar = ((foobar_t *)(data))->bar;
foobar->func = ((foobar_t *)(data))->func;
ret_val = foobar->func(foobar->foo, foobar->bar);
g_print("ret_val: %d n", ret_val);
g_free(foobar);
}
gpointer test_thread_func(gpointer data)
{
foobar_t *foobar = NULL;
GThreadPool *pool = (GThreadPool *)data;
foobar = g_new0(foobar_t, 1);
foobar->foo = 2;
foobar->bar = 3;
foobar->func = test_foobar_add;
g_thread_pool_push(pool, foobar, NULL);
foobar->foo = 2;
foobar->bar = 3;
foobar->func = test_foobar_multi;
g_thread_pool_push(pool, foobar, NULL);
g_free(foobar);
return NULL;
}
void test_thread_pool(void)
{
guint num = 0;
GError *error = NULL;
gint max_threads = 4;
GThreadPool *pool = NULL;
GThread *thd = NULL;
pool = g_thread_pool_new(test_thread_pool_func, NULL, max_threads, TRUE, &error);
thd = g_thread_new("thd", test_thread_func, pool);
g_usleep(100*1000);
g_thread_join(thd);
g_thread_pool_free(pool, TRUE, TRUE);
}
gint main(gint argc, gchar **argv)
{
test_thread_pool();
}

运行结果:

[root@centos7_6 build]# ./glib_theadpool_diff_func_err 
ret_val: 5
ret_val: 6
[root@centos7_6 build]# ./glib_theadpool_diff_func_err 
ret_val: 0
ret_val: 0
[root@centos7_6 build]# ./glib_theadpool_diff_func_err 
ret_val: 5
段错误 (核心已转储)
[root@centos7_6 build]# ./glib_theadpool_diff_func_err 
ret_val: 0
ret_val: 0
[root@centos7_6 build]# ./glib_theadpool_diff_func_err 
ret_val: 6
ret_val: 6

原因出在test_thread_func函数。
本函数可能导致两个问题:
1.两次push完之后,test_thread_func内的foobar被释放,此时线程池的执行函数test_thread_pool_func才刚开始执行,foobar->func地址变为未知,运行结果也未知。
2.第一次push完之后,线程池的一个线程被唤起,test_thread_pool_func开始执行,foobar->func此时为test_foobar_add,运行之后得到的值为5,第二次push完后,线程池还没开始运行,
test_thread_func内的foobar被释放,此时线程池的执行函数test_thread_pool_func才开始执行,foobar->func地址变为未知,导致段错误。

下面是正确的例子。
源码见glib_examplesglib_threadpoolglib_theadpool_diff_func

#include <glib.h>
#include <pthread.h>
typedef int (*foobar_method)(gint a, gint b);
typedef struct foobar_tag {
gint foo;
gint bar;
foobar_method func;
}foobar_t;
static gint test_foobar_add(gint a, gint b)
{
return a + b;
}
static gint test_foobar_multi(gint a, gint b)
{
return a * b;
}
static void test_thread_pool_func(gpointer data, gpointer user_data)
{
gint ret_val = 0;
foobar_t *foobar = NULL;
foobar = (foobar_t *)data;
if(NULL == foobar) {
g_print("input param is NULL n");
return;
}
ret_val = foobar->func(foobar->foo, foobar->bar);
g_print("ret_val: %d n", ret_val);
g_free(foobar);
}
gpointer test_thread_func(gpointer data)
{
foobar_t *foobar1 = NULL;
foobar_t *foobar2 = NULL;
GThreadPool *pool = (GThreadPool *)data;
foobar1 = g_new0(foobar_t, 1);
foobar1->foo = 2;
foobar1->bar = 3;
foobar1->func = test_foobar_add;
g_thread_pool_push(pool, foobar1, NULL);
foobar2 = g_new0(foobar_t, 1);
foobar2->foo = 2;
foobar2->bar = 3;
foobar2->func = test_foobar_multi;
g_thread_pool_push(pool, foobar2, NULL);
return NULL;
}
void test_thread_pool(void)
{
guint num = 0;
GError *error = NULL;
gint max_threads = 4;
GThreadPool *pool = NULL;
GThread *thd = NULL;
pool = g_thread_pool_new(test_thread_pool_func, NULL, max_threads, TRUE, &error);
thd = g_thread_new("thd", test_thread_func, pool);
g_usleep(100*1000);
g_thread_join(thd);
g_thread_pool_free(pool, TRUE, TRUE);
}
gint main(gint argc, gchar **argv)
{
test_thread_pool();
}

多次运行结果:

[root@centos7_6 build]# ./glib_theadpool_diff_func
ret_val: 5
ret_val: 6
[root@centos7_6 build]# ./glib_theadpool_diff_func
ret_val: 6
ret_val: 5
[root@centos7_6 build]# ./glib_theadpool_diff_func
ret_val: 5
ret_val: 6

设置最大线程数

g_thread_pool_set_max_threads函数可以设置线程池最大线程个数。
下面是演示程序。
源码见glib_examplesglib_threadpoolglib_theadpool_set_max_threads

#include <glib.h>
#include <pthread.h>
#define TEST_THREAD_POOL_FIN 9999
GThreadPool *g_pool = NULL;
static void test_thread_pool_func(gpointer data, gpointer user_data)
{
g_print("tid %ld: get data: %d n", (glong)pthread_self(), GPOINTER_TO_INT(data));
g_usleep(50*1000);
if(TEST_THREAD_POOL_FIN == GPOINTER_TO_INT(data)) {
g_print("theadpool free n");
g_thread_pool_free(g_pool, TRUE, TRUE);
}
}
gpointer test_thread_func(gpointer data)
{
GThreadPool *pool = (GThreadPool *)data;
g_thread_pool_push(pool, GINT_TO_POINTER(99), NULL);
g_thread_pool_push(pool, GINT_TO_POINTER(100), NULL);
g_usleep(20*1000); //sleep 20ms to process 99 and 100
g_thread_pool_set_max_threads(pool, 0, NULL);
g_print("set max threads to 0, sleep 1s and set max to 4 n");
g_usleep(1*1000*1000);
g_thread_pool_set_max_threads(pool, 4, NULL);
g_thread_pool_push(pool, GINT_TO_POINTER(101), NULL);
g_thread_pool_push(pool, GINT_TO_POINTER(102), NULL);
g_thread_pool_push(pool, GINT_TO_POINTER(103), NULL);
g_thread_pool_push(pool, GINT_TO_POINTER(104), NULL);
g_thread_pool_push(pool, GINT_TO_POINTER(105), NULL);
g_usleep(60*1000);
g_print("unprocessed: %d n", g_thread_pool_unprocessed(pool));
g_print("max threads: %d n", g_thread_pool_get_max_threads(pool));
g_print("num threads: %d n", g_thread_pool_get_num_threads(pool));
g_print("num unused threads: %d n", g_thread_pool_get_num_unused_threads());
g_print("max unused threads: %d n", g_thread_pool_get_max_unused_threads());
g_thread_pool_push(pool, GINT_TO_POINTER(TEST_THREAD_POOL_FIN), NULL);
return NULL;
}
void test_thread_pool(void)
{
guint num = 0;
GError *error = NULL;
gint max_threads = 3;
GThread *thd = NULL;
g_pool = g_thread_pool_new(test_thread_pool_func, NULL, max_threads, TRUE, &error);
thd = g_thread_new("thd", test_thread_func, g_pool);
g_usleep(500*1000);
g_thread_join(thd);
}
gint main(gint argc, gchar **argv)
{
test_thread_pool();
}

运行结果:

[root@centos7_6 build]# ./glib_theadpool_set_max_threads
tid 140312679347968: get data: 99
tid 140312670955264: get data: 100
set max threads to 0, sleep 1s and set max to 4
tid 140312670955264: get data: 101
tid 140312654169856: get data: 102
tid 140312687740672: get data: 103
tid 140312679347968: get data: 104
tid 140312654169856: get data: 105
unprocessed: 0
max threads: 4
num threads: 4
num unused threads: 0
max unused threads: 2
tid 140312670955264: get data: 9999

对线程中的任务排序

g_thread_pool_set_sort_function可以对线程中的任务自定义排序。
下面是演示程序:
源码见glib_examplesglib_threadpoolglib_theadpool_set_sort_function

#include <glib.h>
#include <pthread.h>
#define TEST_THREAD_POOL_FIN 9999
GThreadPool *g_pool = NULL;
gint _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 n", (glong)pthread_self(), GPOINTER_TO_INT(data));
g_usleep(50*1000);
if(TEST_THREAD_POOL_FIN == GPOINTER_TO_INT(data)) {
g_print("theadpool free n");
g_thread_pool_free(g_pool, TRUE, TRUE);
}
}
gpointer test_thread_func(gpointer data)
{
GThreadPool *pool = (GThreadPool *)data;
g_thread_pool_set_max_threads(pool, 0, NULL);
g_thread_pool_push(pool, GINT_TO_POINTER(99), NULL);
g_thread_pool_push(pool, GINT_TO_POINTER(120), NULL);
g_thread_pool_push(pool, GINT_TO_POINTER(101), NULL);
g_thread_pool_push(pool, GINT_TO_POINTER(106), NULL);
g_thread_pool_push(pool, GINT_TO_POINTER(203), NULL);
g_thread_pool_push(pool, GINT_TO_POINTER(104), NULL);
g_thread_pool_set_sort_function(pool, _test_thread_int_cmp_func, NULL);
g_thread_pool_set_max_threads(pool, 1, NULL);
g_thread_pool_push(pool, GINT_TO_POINTER(TEST_THREAD_POOL_FIN), NULL);
return NULL;
}
void test_thread_pool(void)
{
guint num = 0;
GError *error = NULL;
gint max_threads = 1;
GThread *thd = NULL;
g_pool = g_thread_pool_new(test_thread_pool_func, NULL, max_threads, TRUE, &error);
thd = g_thread_new("thd", test_thread_func, g_pool);
g_usleep(500*1000);
g_thread_join(thd);
}
gint main(gint argc, gchar **argv)
{
test_thread_pool();
}

运行结果:

[root@centos7_6 build]# ./glib_theadpool_set_sort_function
tid 139765831759616: get data: 99
tid 139765831759616: get data: 101
tid 139765831759616: get data: 104
tid 139765831759616: get data: 106
tid 139765831759616: get data: 120
tid 139765831759616: get data: 203
tid 139765831759616: get data: 9999
theadpool free

上述例子创建了最大个数为1的线程池,如果创建的最大个数为2呢?
下面是演示程序:
源码见glib_examplesglib_threadpoolglib_theadpool_set_sort_function_2_threads

#include <glib.h>
#include <pthread.h>
#define TEST_THREAD_POOL_FIN 9999
GThreadPool *g_pool = NULL;
gint _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 n", (glong)pthread_self(), GPOINTER_TO_INT(data));
g_usleep(50*1000);
if(TEST_THREAD_POOL_FIN == GPOINTER_TO_INT(data)) {
g_print("theadpool free n");
g_thread_pool_free(g_pool, TRUE, TRUE);
}
}
gpointer test_thread_func(gpointer data)
{
GThreadPool *pool = (GThreadPool *)data;
g_thread_pool_set_max_threads(pool, 0, NULL);
g_thread_pool_push(pool, GINT_TO_POINTER(99), NULL);
g_thread_pool_push(pool, GINT_TO_POINTER(120), NULL);
g_thread_pool_push(pool, GINT_TO_POINTER(101), NULL);
g_thread_pool_push(pool, GINT_TO_POINTER(106), NULL);
g_thread_pool_push(pool, GINT_TO_POINTER(203), NULL);
g_thread_pool_push(pool, GINT_TO_POINTER(104), NULL);
g_thread_pool_set_sort_function(pool, _test_thread_int_cmp_func, NULL);
g_thread_pool_set_max_threads(pool, 1, NULL);
g_thread_pool_push(pool, GINT_TO_POINTER(TEST_THREAD_POOL_FIN), NULL);
return NULL;
}
void test_thread_pool(void)
{
guint num = 0;
GError *error = NULL;
gint max_threads = 2; //set initial max threads to 2
GThread *thd = NULL;
g_pool = g_thread_pool_new(test_thread_pool_func, NULL, max_threads, TRUE, &error);
thd = g_thread_new("thd", test_thread_func, g_pool);
g_usleep(500*1000);
g_thread_join(thd);
}
gint main(gint argc, gchar **argv)
{
test_thread_pool();
}

运行结果:

[root@centos7_6 build]# ./glib_theadpool_set_sort_function_2_threads
tid 140527418357504: get data: 99
tid 140527409964800: get data: 120
tid 140527418357504: get data: 101
tid 140527418357504: get data: 104
tid 140527418357504: get data: 106
tid 140527418357504: get data: 203
tid 140527418357504: get data: 9999
theadpool free

可以看到有两个tid,说明线程池创建时已经有线程在运行了,即使设置了g_thread_pool_set_max_threads为0,重新设置为非0时,之前创建的线程会继续运行。

如果在线程池创建时初始化指定最大线程数是4呢?
下面是演示程序:
源码见glib_examplesglib_threadpoolglib_theadpool_set_sort_function_4_threads

#include <glib.h>
#include <pthread.h>
#define TEST_THREAD_POOL_FIN 9999
GThreadPool *g_pool = NULL;
gint _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 n", (glong)pthread_self(), GPOINTER_TO_INT(data));
g_usleep(50*1000);
if(TEST_THREAD_POOL_FIN == GPOINTER_TO_INT(data)) {
g_print("theadpool free n");
g_thread_pool_free(g_pool, TRUE, TRUE);
}
}
gpointer test_thread_func(gpointer data)
{
GThreadPool *pool = (GThreadPool *)data;
g_thread_pool_set_max_threads(pool, 0, NULL);
g_thread_pool_push(pool, GINT_TO_POINTER(99), NULL);
g_thread_pool_push(pool, GINT_TO_POINTER(120), NULL);
g_thread_pool_push(pool, GINT_TO_POINTER(101), NULL);
g_thread_pool_push(pool, GINT_TO_POINTER(106), NULL);
g_thread_pool_push(pool, GINT_TO_POINTER(203), NULL);
g_thread_pool_push(pool, GINT_TO_POINTER(104), NULL);
g_thread_pool_set_sort_function(pool, _test_thread_int_cmp_func, NULL);
g_thread_pool_set_max_threads(pool, 1, NULL);
g_thread_pool_push(pool, GINT_TO_POINTER(TEST_THREAD_POOL_FIN), NULL);
return NULL;
}
void test_thread_pool(void)
{
guint num = 0;
GError *error = NULL;
gint max_threads = 4; //set initial max threads to 4
GThread *thd = NULL;
g_pool = g_thread_pool_new(test_thread_pool_func, NULL, max_threads, TRUE, &error);
thd = g_thread_new("thd", test_thread_func, g_pool);
g_usleep(500*1000);
g_thread_join(thd);
}
gint main(gint argc, gchar **argv)
{
test_thread_pool();
}

运行结果:

[root@centos7_6 build]# ./glib_theadpool_set_sort_function_4_threads
tid 139887694608128: get data: 99
tid 139887686215424: get data: 101
tid 139887711393536: get data: 120
tid 139887694608128: get data: 104
tid 139887694608128: get data: 106
tid 139887694608128: get data: 203
tid 139887694608128: get data: 9999
theadpool free
[root@centos7_6 build]# ./glib_theadpool_set_sort_function_4_threads
tid 139875977897728: get data: 99
tid 139875877648128: get data: 101
tid 139875969505024: get data: 120
tid 139875986290432: get data: 104
tid 139875877648128: get data: 106
tid 139875877648128: get data: 203
tid 139875877648128: get data: 9999
theadpool free
[root@centos7_6 build]# ./glib_theadpool_set_sort_function_4_threads
tid 140545881827072: get data: 99
tid 140545881827072: get data: 101
tid 140545881827072: get data: 104
tid 140545881827072: get data: 106
tid 140545881827072: get data: 120
tid 140545881827072: get data: 203
tid 140545881827072: get data: 9999
theadpool free

上述结果表明:
线程池执行任务时,创建的线程变得不确定起来,有可能是4个,有可能是3个,也有可能只有1个。原因是在线程池中创建线程也是需要消耗时间的,如果在线程创建之前就对线程池进行了g_thread_pool_set_max_threads(0),则新的线程就无法创建了。

下面用程序来验证一下。在线程池创建完后休眠50ms,再设置最大个数。
源码见glib_examplesglib_threadpoolglib_theadpool_set_sort_function_4_threads_sleep

#include <glib.h>
#include <pthread.h>
#define TEST_THREAD_POOL_FIN 9999
GThreadPool *g_pool = NULL;
gint _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 n", (glong)pthread_self(), GPOINTER_TO_INT(data));
g_usleep(50*1000);
if(TEST_THREAD_POOL_FIN == GPOINTER_TO_INT(data)) {
g_print("theadpool free n");
g_thread_pool_free(g_pool, TRUE, TRUE);
}
}
gpointer test_thread_func(gpointer data)
{
GThreadPool *pool = (GThreadPool *)data;
g_thread_pool_set_max_threads(pool, 0, NULL);
g_thread_pool_push(pool, GINT_TO_POINTER(99), NULL);
g_thread_pool_push(pool, GINT_TO_POINTER(120), NULL);
g_thread_pool_push(pool, GINT_TO_POINTER(101), NULL);
g_thread_pool_push(pool, GINT_TO_POINTER(106), NULL);
g_thread_pool_push(pool, GINT_TO_POINTER(203), NULL);
g_thread_pool_push(pool, GINT_TO_POINTER(104), NULL);
g_thread_pool_set_sort_function(pool, _test_thread_int_cmp_func, NULL);
g_thread_pool_set_max_threads(pool, 1, NULL);
g_thread_pool_push(pool, GINT_TO_POINTER(TEST_THREAD_POOL_FIN), NULL);
return NULL;
}
void test_thread_pool(void)
{
guint num = 0;
GError *error = NULL;
gint max_threads = 4;
GThread *thd = NULL;
g_pool = g_thread_pool_new(test_thread_pool_func, NULL, max_threads, TRUE, &error);
g_usleep(50*1000); //sleep 50 ms, wait threadpool threads create
thd = g_thread_new("thd", test_thread_func, g_pool);
g_usleep(500*1000);
g_thread_join(thd);
}
gint main(gint argc, gchar **argv)
{
test_thread_pool();
}

运行结果:

[root@centos7_6 build]# ./glib_theadpool_set_sort_function_4_threads_sleep
tid 139845579298560: get data: 120
tid 139845587691264: get data: 99
tid 139845562513152: get data: 101
tid 139845570905856: get data: 104
tid 139845562513152: get data: 106
tid 139845562513152: get data: 203
tid 139845562513152: get data: 9999
theadpool free
[root@centos7_6 build]# ./glib_theadpool_set_sort_function_4_threads_sleep
tid 139912332961536: get data: 101
tid 139912341354240: get data: 99
tid 139912349746944: get data: 120
tid 139912358139648: get data: 104
tid 139912349746944: get data: 106
tid 139912349746944: get data: 203
tid 139912349746944: get data: 9999
theadpool free
[root@centos7_6 build]# ./glib_theadpool_set_sort_function_4_threads_sleep
tid 139784953247488: get data: 120
tid 139784936462080: get data: 106
tid 139784961640192: get data: 99
tid 139784944854784: get data: 101
tid 139784936462080: get data: 104
tid 139784936462080: get data: 203
tid 139784936462080: get data: 9999
theadpool free

运行多次都可以发现,有4个线程被运行。需要注意的是任务排序结果仍不正确。

最后

以上就是飞快树叶为你收集整理的5_04_GLib库入门与实践_线程池的全部内容,希望文章能够帮你解决5_04_GLib库入门与实践_线程池所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(49)

评论列表共有 0 条评论

立即
投稿
返回
顶部