Thread Pools

Thread Pools — pools of threads to execute work concurrently

Synopsis

#include <glib.h>

struct              GThreadPool;
GThreadPool *       g_thread_pool_new                   (GFunc func,
                                                         gpointer user_data,
                                                         gint max_threads,
                                                         gboolean exclusive,
                                                         GError **error);
void                g_thread_pool_push                  (GThreadPool *pool,
                                                         gpointer data,
                                                         GError **error);
void                g_thread_pool_set_max_threads       (GThreadPool *pool,
                                                         gint max_threads,
                                                         GError **error);
gint                g_thread_pool_get_max_threads       (GThreadPool *pool);
guint               g_thread_pool_get_num_threads       (GThreadPool *pool);
guint               g_thread_pool_unprocessed           (GThreadPool *pool);
void                g_thread_pool_free                  (GThreadPool *pool,
                                                         gboolean immediate,
                                                         gboolean wait_);
void                g_thread_pool_set_max_unused_threads
                                                        (gint max_threads);
gint                g_thread_pool_get_max_unused_threads
                                                        (void);
guint               g_thread_pool_get_num_unused_threads
                                                        (void);
void                g_thread_pool_stop_unused_threads   (void);
void                g_thread_pool_set_sort_function     (GThreadPool *pool,
                                                         GCompareDataFunc func,
                                                         gpointer user_data);
void                g_thread_pool_set_max_idle_time     (guint interval);
guint               g_thread_pool_get_max_idle_time     (void);

Description

Sometimes you wish to asynchronously fork out the execution of work and continue working in your own thread. If that will happen often, the overhead of starting and destroying a thread each time might be too high. In such cases reusing already started threads seems like a good idea. And it indeed is, but implementing this can be tedious and error-prone.

Therefore GLib provides thread pools for your convenience. An added advantage is, that the threads can be shared between the different subsystems of your program, when they are using GLib.

To create a new thread pool, you use g_thread_pool_new(). It is destroyed by g_thread_pool_free().

If you want to execute a certain task within a thread pool, you call g_thread_pool_push().

To get the current number of running threads you call g_thread_pool_get_num_threads(). To get the number of still unprocessed tasks you call g_thread_pool_unprocessed(). To control the maximal number of threads for a thread pool, you use g_thread_pool_get_max_threads() and g_thread_pool_set_max_threads().

Finally you can control the number of unused threads, that are kept alive by GLib for future use. The current number can be fetched with g_thread_pool_get_num_unused_threads(). The maximal number can be controlled by g_thread_pool_get_max_unused_threads() and g_thread_pool_set_max_unused_threads(). All currently unused threads can be stopped by calling g_thread_pool_stop_unused_threads().

Details

struct GThreadPool

struct GThreadPool {
  GFunc func;
  gpointer user_data;
  gboolean exclusive;
};

The GThreadPool struct represents a thread pool. It has three public read-only members, but the underlying struct is bigger, so you must not copy this struct.

GFunc func;

the function to execute in the threads of this pool

gpointer user_data;

the user data for the threads of this pool

gboolean exclusive;

are all threads exclusive to this pool

g_thread_pool_new ()

GThreadPool *       g_thread_pool_new                   (GFunc func,
                                                         gpointer user_data,
                                                         gint max_threads,
                                                         gboolean exclusive,
                                                         GError **error);

这个函数创建一个新的线程池。

每当你调用 g_thread_pool_push() 时,要么创建一个新的线程,要么复用线程池里一 个还未被使用的线程。至多 max_threads 个线程在线程池里并行运行。若 max_threads = -1 则表示允许该线程池创建无数个线程。新创建的或者复用的线程将 执行 func 函数,并且传递两个参数。第一个参数是 g_thread_pool_push() 里面的数 据,也即要执行的任务,第二个参数则是 user_data

参数 exclusive 确定线程池里的线程是否为全局共享线程。如果 exclusiveTRUEmax_threads 个线程将立即开始并且一直独占的运行在这个线程池,直到通 过 g_thread_pool_free() 销毁它;如果 exclusiveFALSE,则线程被创建,并且 当需要时和其他非独占性线程池共享。这也就意味着,在独占性线程池里 max_threads may 不能为 -1 。

error 能通过设置 NULL 来忽略,或者用非NULL 来报告错误。一个错误仅会发生在 exclusive 设置为 TRUE 和并非所有 max_threads 个线程都能被创建时。

func :

在新线程池的线程里执行的函数

user_data :

每次func被调用时,user_data将被作为其参数传递过去

max_threads :

新线程池中并行线程的最大数目,-1代表无限制

exclusive :

让该线程池使用独占模式?

error :

返回发生错误的位置

Returns :

新的 GAsyncQueue

g_thread_pool_push ()

void                g_thread_pool_push                  (GThreadPool *pool,
                                                         gpointer data,
                                                         GError **error);

data 插入任务列表,让 pool 来执行。当正在运行线程的数量低于允许线程的最 大值,一个新的线程将被启动(或者复用),并根据其属性提交给 g_thread_pool_new() 。除此之外, data 将一直保存在任务队列之中,直到线程池里的线程完成了其先 前的任务然后处理 data

error 能通过设置 NULL 来忽略,或者用非NULL 来报告错误。一个错误仅会发生在 一个新的线程不能被创建时。在这样的情况下, data 只是简单的追加到任务队列里。

pool :

一个 GThreadPool

data :

pool 的一个新任务

error :

返回发生错误的位置

g_thread_pool_set_max_threads ()

void                g_thread_pool_set_max_threads       (GThreadPool *pool,
                                                         gint max_threads,
                                                         GError **error);

pool 设置其允许线程数目的最大值。值为 -1 的话,则代表无限制。

设置 max_threads 为 0 则以为着停止 pool 所有的任务。这样的冻结将一直有效, 直到 max_threads 被设置为一个非0值。

一个线程是永远不会终止的,而是循环调用 func ,例如 g_thread_pool_new() 所提 供的。反而,线程最大值仅影响 g_thread_pool_push() 里新线程的分配。如果一个新 的线程被分配,无论如何当前 pool 里运行的线程数目要小于最大值。

error 能通过设置 NULL 来忽略,或者用非NULL 来报告错误。一个错误仅会发生在 一个新的线程不能被创建时。

pool :

一个 GThreadPool

max_threads :

pool 中线程的最大值

error :

返回发生错误的位置

g_thread_pool_get_max_threads ()

gint                g_thread_pool_get_max_threads       (GThreadPool *pool);

返回 pool 线程数目的最大值。

pool :

一个 GThreadPool

Returns :

线程数目的最大值

g_thread_pool_get_num_threads ()

guint               g_thread_pool_get_num_threads       (GThreadPool *pool);

返回 pool 里当前正在运行线程的数目。

pool :

一个 GThreadPool

Returns :

当前正在运行线程的数目

g_thread_pool_unprocessed ()

guint               g_thread_pool_unprocessed           (GThreadPool *pool);

返回 pool 里仍未处理的任务的数目。

pool :

一个 GThreadPool

Returns :

未处理任务的数目

g_thread_pool_free ()

void                g_thread_pool_free                  (GThreadPool *pool,
                                                         gboolean immediate,
                                                         gboolean wait_);

释放所有为 pool 分配的资源。

如果 immediateTRUE ,则停止 pool 处理新的任务。反之,在最后一个任务处 理完之前, pool 是不会被销毁的。请注意,无论如何,在线程池处理一个任务的过程 中,线程池中的线程是不会被中断的。相反,在 pool 被销毁之前,所有仍在运行的线 程将完成它们的任务。

如果 wait_TRUE,则在所有已经准备或者正在执行的任务完成之前,是不会返回 的(这依赖于 immediate ,是所有的任务,还是当前正在运行的任务)。否则,函数 立即返回。

在调用这个函数之后, pool 将不能被使用。

pool :

一个 GThreadPool

immediate :

pool 立即关闭 ?

wait_ :

让函数等待所有任务完成 ?

g_thread_pool_set_max_unused_threads ()

void                g_thread_pool_set_max_unused_threads
                                                        (gint max_threads);

设置未使用的最大线程数为 max_threads。如果 max_threads 为-1,则强制未使用的 线程数为无限制。

max_threads :

未使用的最大线程数

g_thread_pool_get_max_unused_threads ()

gint                g_thread_pool_get_max_unused_threads
                                                        (void);

返回允许未使用线程数目的最大值。

Returns :

未使用线程数目的最大值

g_thread_pool_get_num_unused_threads ()

guint               g_thread_pool_get_num_unused_threads
                                                        (void);

返回当前未使用线程的数目。

Returns :

当前未使用线程的数目

g_thread_pool_stop_unused_threads ()

void                g_thread_pool_stop_unused_threads   (void);

停止所有当前未使用的线程。这不会改变未使用线程数目的最大值。此函数可用于正常 的停止所有未使用的线程。例如:从 g_timeout_add() 中使用。


g_thread_pool_set_sort_function ()

void                g_thread_pool_set_sort_function     (GThreadPool *pool,
                                                         GCompareDataFunc func,
                                                         gpointer user_data);

设置用来排序任务列表的函数。这使得可以通过 func 决定的优先级来处理任务,而不 仅仅只是为了把它们添加到线程池中。

请注意,如果最大线程数大于1,则不能100%的保证线程的执行顺序。线程由操作系统调 度,并随机执行。并且不能假定为线程按照创建它们时的顺序来执行。

pool :

一个 GThreadPool

func :

GCompareDataFunc 用于将任务队列排序。这个函数需要传递两个任务。如果 两个任务的处理顺序无关紧要,就返回0;如果第一个任务应该优先处理,就返回一个负 值;如果第二个任务应该被优先处理,就返回一个正值。

user_data :

传递给 func 的用户数据。

Since 2.10


g_thread_pool_set_max_idle_time ()

void                g_thread_pool_set_max_idle_time     (guint interval);

这个函数用于设置最大值 interval ,也就是线程池中一个线程等待新任务的最大空闲 时间。这个函数类似于在常规的超时时调用 g_thread_pool_stop_unused_threads() , 不同的是,这个函数是以一个线程作为基本单位。

通过把 interval 设置为0,来使空闲的线程不会停止。 这个函数让 g_async_queue_timed_pop() 的使用,使用了 interval

interval :

一个线程能被闲置的最大值, interval (1/1000 分之一秒)。

Since 2.10


g_thread_pool_get_max_idle_time ()

guint               g_thread_pool_get_max_idle_time     (void);

这个函数将返回最大值 interval ,也就是线程池中一个线程等待新任务的最大空闲时 间。

如果该函数返回0,线程池中的线程在对新任务的等待是没有停止过的。

Returns :

最大值 interval ,在线程池中等待新任务前停止线程的最大空闲时间 (1/1000分之一秒)。

Since 2.10

See Also

GThread

GLib thread system.