gtask笔记

gtask笔记

码农世界 2024-05-27 前端 81 次浏览 0个评论
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 
#include 
}
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

转载请注明来自码农世界,本文标题:《gtask笔记》

百度分享代码,如果开启HTTPS请参考李洋个人博客
每一天,每一秒,你所做的决定都会改变你的人生!

发表评论

快捷回复:

评论列表 (暂无评论,81人围观)参与讨论

还没有评论,来说两句吧...

Top