gtask笔记

1、创建Task
GTask *g_task_new (gpointer  source_object, GCancellable *cancellable, GAsyncReadyCallback  callback, gpointer callback_data);
source_object:GObject对象,拥有者
cancellable:可否取消
callback:task完成后调用函数
callback_data:task完成后调用函数数据参数
2、设置数据
void g_task_set_task_data(GTask *task, gpointer task_data GDestroyNotify task_data_destroy);
处理函数使用task_data方式:typedef void (*GTaskThreadFunc)(GTask *task,gpointer source_object,gpointer task_data,GCancellable *cancellable);
3、同步执行和异步执行,注: 一定调用 g_task_return_pointer或者g_task_return_error返回
void g_task_run_in_thread(GTask *task,GTaskThreadFunc task_func);
void g_task_run_in_thread_sync(GTask *task, GTaskThreadFunc task_func);
调用时机:调用task完成后的回调函数, GAsyncReadyCallback的调用时机 是main event loop的下一次迭代。
4、执行回调函数
typedef void (*GAsyncReadyCallback) (GObject *source_object,GAsyncResult *res,gpointer data);
5、示例
extern "C"{
#include "glib.h"
#include "glib-object.h"
#include "gio/gio.h
#include <stdio.h>
#include <stdlib.h>
}
typedef int CakeFlavor;
typedef int CakeFrostingType;

typedef struct {
    guint radius;
    CakeFlavor flavor;
    CakeFrostingType frosting;
    char *message;
} CakeData;

typedef GObject Cake;

static void cake_data_free(CakeData *cake_data)
{
    printf("main thread %p: %s\n", g_thread_self(), __func__);
    g_free(cake_data->message);
    g_slice_free(CakeData, cake_data);
}


static Cake *bake_cake(GObject *self, guint radius, CakeFlavor flavor,
               CakeFrostingType frosting, char *message,
               GCancellable *cancellable, GError **error)
{
    printf("end------sub thread %p: %s\n\n", g_thread_self(), __func__);
    return (Cake *)g_object_new(G_TYPE_OBJECT, NULL);
}


static void bake_cake_thread(GTask *task, gpointer source_object,
                 gpointer task_data, GCancellable *cancellable)
{
    GObject *self = (GObject *)source_object;
    CakeData *cake_data = (CakeData *)task_data;
    Cake *cake;
    GError *error = NULL;
    printf("\nstart-----sub thread %p: %s\n", g_thread_self(), __func__);
    cake = bake_cake(self, cake_data->radius, cake_data->flavor,
             cake_data->frosting, cake_data->message, cancellable,
             &error);
    if (cake)
        g_task_return_pointer(task, cake, g_object_unref);
    else
        g_task_return_error(task, error);

    if (g_task_set_return_on_cancel (task, FALSE)){
         g_task_return_pointer (task, cake, g_object_unref);
    }
}

static void baker_bake_cake_async(GObject *self, guint radius, CakeFlavor flavor,
                  CakeFrostingType frosting,
                  const char *message,
                  GCancellable *cancellable,
                  GAsyncReadyCallback callback,
                  gpointer user_data)
{
    CakeData *cake_data;
    GTask *task;


    printf("main thread %p: %s\n", g_thread_self(), __func__);
    cake_data = g_slice_new(CakeData);
    cake_data->radius = radius;
    cake_data->flavor = flavor;
    cake_data->frosting = frosting;
    cake_data->message = g_strdup(message);

    task = g_task_new(self, cancellable, callback, user_data);
    g_task_set_task_data(task, cake_data, (GDestroyNotify)cake_data_free);
//    g_task_set_return_on_cancel (task, TRUE);
    g_task_run_in_thread(task, bake_cake_thread);
//    g_task_set_check_cancellable(task,TRUE);
    g_object_unref(task);
}

static Cake * baker_bake_cake_sync(GObject *self, guint radius, CakeFlavor flavor,
                  CakeFrostingType frosting,
                  const char *message,
                  GCancellable *cancellable,
                  GAsyncReadyCallback callback,
                  gpointer user_data)
{
    CakeData *cake_data;
    GTask *task;
    printf("main thread %p: %s\n", g_thread_self(), __func__);
    cake_data = g_slice_new(CakeData);
    cake_data->radius = radius;
    cake_data->flavor = flavor;
    cake_data->frosting = frosting;
    cake_data->message = g_strdup(message);

    task = g_task_new(self, cancellable, NULL, NULL);
    g_task_set_task_data(task, cake_data, (GDestroyNotify)cake_data_free);
//    g_task_set_return_on_cancel (task, TRUE);
    g_task_run_in_thread_sync(task, bake_cake_thread);


    Cake *cake;
    GError *error = NULL;
    cake = (Cake *)g_task_propagate_pointer (task, &error);
    printf("baker_bake_cake_sync cake: %p\n", cake);
    g_object_unref(task);
    return cake;
}

static Cake *baker_bake_cake_finish(GObject *self, GAsyncResult *res,
                    GError **error)
{
    g_return_val_if_fail(g_task_is_valid(res, self), NULL);
    printf("main thread %p: %s\n", g_thread_self(), __func__);
    return (Cake *)g_task_propagate_pointer(G_TASK(res), error);
}

static void my_callback(GObject *source_object, GAsyncResult *res,
            gpointer user_data)
{
    GObject *baker = (GObject *)source_object;
    GMainLoop *loop = (GMainLoop *)user_data;
    Cake *cake;
    GError *error = NULL;
    printf("main thread %p: %s\n", g_thread_self(), __func__);
    cake = baker_bake_cake_finish(baker, res, &error);
    printf("A cake is baked: %p\n", cake);

    // But discard it. I prefer pudding.
    g_object_unref(cake);

    // Stop cooking.
    g_main_loop_quit(loop);
}

int main(void)
{
    GObject *baker = (GObject *)g_object_new(G_TYPE_OBJECT, NULL);
    GCancellable *cancellable = g_cancellable_new();

    GMainLoop *loop = g_main_loop_new(NULL, FALSE);
    Cake * cake = baker_bake_cake_sync(baker, 10, 20, 30, "sync", cancellable, my_callback, loop);
    g_object_unref(cake);

    baker_bake_cake_async(baker, 10, 20, 30, "async", cancellable, my_callback, loop);
    g_object_unref(cancellable);
    printf("main thread %p: start event loop.\n", g_thread_self());
    g_main_loop_run(loop);

    g_main_loop_unref(loop);
    g_object_unref(baker);

    return EXIT_SUCCESS;
}

输出结果:
main thread 000001F6F9BED030: baker_bake_cake_sync
start-----sub thread 000001F6F9BEF0C0: bake_cake_thread
end------sub thread 000001F6F9BEF0C0: bake_cake
baker_bake_cake_sync cake: 000001F6F9BEE140
main thread 000001F6F9BED030: cake_data_free
main thread 000001F6F9BED030: baker_bake_cake_async
main thread 000001F6F9BED030: start event loop.
start-----sub thread 000001F6F9BEF0C0: bake_cake_thread
end------sub thread 000001F6F9BEF0C0: bake_cake
main thread 000001F6F9BED030: my_callback
main thread 000001F6F9BED030: baker_bake_cake_finish
A cake is baked: 000001F6F9BEE380
main thread 000001F6F9BED030: cake_data_free
  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值