1. GTask 是继承于 GObject 的标准对象。使用GObject标准引用计数。使用 g_object_unref 解引用。

  2. GTask 内部是用非独占GThreadPool去执行 GTask 需要执行 ‘g_task_run_in_thread’ 设定的线程函数。(注意:task_pool是全局静态变量,也就说所有创建的GTask对象都是使用这个线程池去运行要执行的函数)。

  3. GTask 任务中线程函数执行完毕后,会执行 g_task_new 设定的 @callback 函数。

  4. GTask 一个对象只能执行一次 g_task_run_in_thread 任务线程函数。(内部没有重置GTask的函数,让任务重新运行)

1 GTask对象

/* task.c */
struct _GTaskClass
{
  GObjectClass parent_class;
};

struct _GTask {
  GObject parent_instance;

  gpointer source_object;
  gpointer source_tag;
  gchar *name;  /* (owned); may only be modified before the #GTask is threaded */

  gpointer task_data;
  GDestroyNotify task_data_destroy;

  GMainContext *context;
  gint64 creation_time;
  gint priority;
  GCancellable *cancellable;

  GAsyncReadyCallback callback;
  gpointer callback_data;

  GTaskThreadFunc task_func;
  GMutex lock;
  GCond cond;

  /* This can’t be in the bit field because we access it from TRACE(). */
  gboolean thread_cancelled;

  /* Protected by the lock when task is threaded: */
  guint thread_complete : 1; /* 线程执行函数完成会给该变量赋值TRUE */
  guint return_on_cancel : 1;
  guint : 0;

  /* Unprotected, but written to when task runs in thread: */
  guint completed : 1; 
  guint had_error : 1;
  guint result_set : 1;
  guint ever_returned : 1; /* 如果线程任务执行完毕,会给该值赋TRUE */
  guint : 0;

  /* Read-only once task runs in thread: */
  guint check_cancellable : 1;
  guint synchronous : 1;
  guint blocking_other_task : 1;
  guint name_is_static : 1;

  /* 任务返回的结果,比如返回:错误,整形,布尔,指针 */
  GError *error;
  union {
    gpointer pointer;
    gssize   size;
    gboolean boolean;
  } result;
  GDestroyNotify result_destroy;
};

2 GTask相关函数

/**
 * @brief: 创建GTask对象
 * @param source_object: 这其实也就是指针,这个指针会传给 @callback 函数
 * @param cancellable: 可取消对象,用来取消任务(我们可以在线程函数中检测该对象,外部是否发起取消请求)
 * @param callback: 线程任务函数执行完毕后,会调用该函数(该函数会在g_main_context_ref_thread_default的上下文下调用,如果没有,则是g_main_context_default返回的上下文下调用)
 * @param callback_data: 执行@callback时候的数据
*/
GTask *
g_task_new (gpointer              source_object,
            GCancellable         *cancellable,
            GAsyncReadyCallback   callback,
            gpointer              callback_data);

/**
 * @brief: 设定执行任务线程函数的时候所需的数据
*/
g_task_set_task_data (GTask          *task,
                      gpointer        task_data,
                      GDestroyNotify  task_data_destroy);

/**
 * @brief: 设定 @task_func 任务函数去执行,这个函数不会阻塞等待任务函数执行完毕
*/
void
g_task_run_in_thread (GTask           *task,
                      GTaskThreadFunc  task_func);

/**
 * @brief: 设定 @task_func 任务函数去执行,这个函数会阻塞等待任务函数执行完毕
*/
void
g_task_run_in_thread_sync (GTask           *task,
                           GTaskThreadFunc  task_func);

/**
 * @brief: 设置任务结果值,方便其他函数获取线程函数执行结果。
 * @note: 一般在任务线程执行函数中调用。
*/
void
g_task_return_int (GTask  *task,
                   gssize  result);

/**
 * @brief: 获取任务结果值值
 * @note: 一般要先判断任务执行过程中是否有错误产生,再去使用该任务结果值。
*/
gssize
g_task_propagate_int (GTask   *task,
                      GError **error);

/**
 * @brief: 如果不设置该函数,只要可取消对象设置了取消,任务一定会返回错误(取消错误)
*/
gboolean
g_cancellable_is_cancelled (GCancellable *cancellable);