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
还没有评论,来说两句吧...