当前位置: 首页 > news >正文

十三、GIO GTask

GTask表示管理一个可取消的“任务task”

GCancellable

GCancellable是一个线程安全的操作取消栈,用于整个GIO,以允许取消同步和异步操作。

它继承于GObject对象,不是一个单纯的结构体

相关函数

g_task_new

GTask*
g_task_new (GObject* source_object,GCancellable* cancellable,GAsyncReadyCallback callback,gpointer callback_data
)

创建一个作用于source_object的GTask,它最终会在[thread-default main context][g-main-context-push-thread-default]中被使用去调用callback

在异步方法的“start”方法中调用它,并在异步操作中传递GTask。可以使用g_task_set_task_data()将特定于任务的数据附加到对象上,稍后可以通过g_task_get_task_data()获取这些数据。

默认情况下,如果cancelable被取消,那么任务的返回值总是G_IO_ERROR_CANCELLED,即使任务在取消之前已经完成。取消操作可能意味着该任务所依赖的其他对象已经被销毁,这种情况下的处理可以简化。如果你不想要这种行为,可以使用g_task_set_check_cancellable()来改变它。

g_task_set_task_data

void
g_task_set_task_data (GTask* task,gpointer task_data,GDestroyNotify task_data_destroy
)

设定task任务的数据

g_task_run_in_thread

void
g_task_run_in_thread (GTask* task,GTaskThreadFunc task_func
)

在另一个线程中运行task_func。当task_func返回时,任务的GAsyncReadyCallback将在任务的GMainContext中调用(任务实在那个GMainContext上下文中创建的,就那个上下文中执行回调函数)。

这里会对task进行一个ref,直到task完成。

有关如何处理task_func的更多细节,请参阅GTaskThreadFunc。

尽管GLib当前对通过g_task_run_in_thread()排队的任务进行速率限制,但大家不应该假定它总是这样做。如果你有很多任务要运行(几十个任务),但又不希望它们同时运行,那么一次只应该将有限数量的任务(大约10个)放入队列。

#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;
typedef GObject Baker; /* 面包师 */static void
cake_data_free (CakeData *cake_data) {g_print ("%p: %s\n", g_thread_self(), __func__);g_free (cake_data->message);/*  */g_slice_free (CakeData, cake_data);
}/* 烤面包 */
static Cake *
bake_cake(Baker *self, guint radius, CakeFlavor flavor,CakeFrostingType frosting, char *message,GCancellable *cancellable, GError **error)
{printf("%p: %s\n", g_thread_self(), __func__);return g_object_new(G_TYPE_OBJECT, NULL);
}static void 
bake_cake_thread(GTask *task, gpointer source_object,gpointer task_data, GCancellable *cancellable)
{Baker *self = source_object;CakeData *cake_data = task_data;Cake *cake;GError *error = NULL;printf("%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);elseg_task_return_error(task, error);
}static void 
baker_bake_cake_async(Baker *self, guint radius, CakeFlavor flavor,CakeFrostingType frosting,const char *message,GCancellable *cancellable,GAsyncReadyCallback callback,gpointer user_data) {CakeData *cake_data;GTask *task;printf("%p: %s\n", g_thread_self(), __func__);/* 切片分配内存(这是一个便利的宏,从slice allocator分配内存) */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);/* 把数据附加在task上 */g_task_set_task_data(task, cake_data, (GDestroyNotify)cake_data_free);g_task_run_in_thread(task, bake_cake_thread);g_object_unref(task);
}static Cake *
baker_bake_cake_finish(Baker *self, GAsyncResult *res,GError **error) {g_return_val_if_fail(g_task_is_valid(res, self), NULL);printf("%p: %s\n", g_thread_self(), __func__);return g_task_propagate_pointer(G_TASK(res), error);
}static void 
my_callback(GObject *source_object, GAsyncResult *res,gpointer user_data) {/* 创建一个面包师 */Baker *baker = (Baker *)source_object;GMainLoop *loop = (GMainLoop *)user_data;Cake *cake;GError *error = NULL;printf("%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) {Baker *baker = g_object_new(G_TYPE_OBJECT, NULL);GCancellable *cancellable = g_cancellable_new();GMainLoop *loop = g_main_loop_new(NULL, FALSE);printf("%p: %s\n", g_thread_self(), __func__);baker_bake_cake_async(baker, 10, 20, 30, "emit", cancellable,1, loop);g_object_unref(cancellable);printf("%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;
}

异步操作

GTask最常见的用法是作为一个GAsyncResult,在异步操作期间管理数据。你可以在“start”方法中调用g_task_new(),然后调用g_task_set_task_data()以及类似的方法,如果你需要保留一些与任务相关的额外数据,然后通过异步操作传递任务对象。最终,您将调用诸如g_task_return_pointer()或g_task_return_error()之类的方法,该方法将保存您给它的值,然后在创建它的[thread-default main context][g-main-context-push-thread-default]中调用任务的回调函数(如果需要,首先等待主循环的下一次迭代)。调用者将把GTask传递回操作的finish函数(作为GAsyncResult),你可以使用g_task_propagate_pointer()或类似的函数来提取返回值。

使用GTask要求thread-default的GMainContext从GTask构建时开始运行,至少直到任务完成并释放其数据。

下面是一个使用GTask作为GAsyncResult的例子:

相关文章:

十三、GIO GTask

GTask表示管理一个可取消的“任务task” GCancellable GCancellable是一个线程安全的操作取消栈&#xff0c;用于整个GIO&#xff0c;以允许取消同步和异步操作。 它继承于GObject对象&#xff0c;不是一个单纯的结构体 相关函数 g_task_new GTask* g_task_new (GObject*…...

ch4_1存储器

1. 存储器的类型 1.1 按照存储介质来分类 半导体存储器&#xff1a; TTL&#xff0c; MOS 易失性 磁表面存储器&#xff1a; 磁头&#xff0c; 载磁体&#xff1b; 磁芯存储器&#xff1a; 硬磁材料&#xff0c; 环状元件 光盘存储器: 激光&#xff0c; 磁光材料; 1.2 按…...

Doris通过Flink CDC接入MySQL实战

1. 创建MySQL库表&#xff0c;写入demo数据 登录测试MySQL mysql -u root -pnew_password创建MySQL库表&#xff0c;写入demo数据 CREATE DATABASE emp_1;USE emp_1; CREATE TABLE employees_1 (emp_no INT NOT NULL,birth_date DATE NOT NULL,…...

搭建zookeeper高可用集群详细步骤

目录 一、虚拟机设置 1.新建一台虚拟机并克隆三台&#xff0c;配置自定义 2.修改四台虚拟机的主机名并立即生效 3.修改四台虚拟机的网络信息 4.重启四台虚拟机的网络服务并测试网络连接 5.重启四台虚拟机&#xff0c;启动后关闭四台虚拟机的防火墙 6.在第一台虚拟机的/e…...

Scala 变量和数据类型(第二章)

第二章、变量和数据类型2.1 注释2.2 变量和常量&#xff08;重点&#xff09;2.3 标识符的命名规范2.4 字符串输出2.5 键盘输入2.6 数据类型&#xff08;重点&#xff09;回顾&#xff1a;Java数据类型Scala数据类型2.7 整数类型&#xff08;Byte、Short、Int、Long&#xff09…...

【JVM基础内容速查表】JVM基础知识 默认参数 GC命令 工具使用 JVM参数设置、说明、使用方法、注意事项等(持续更新)

目录一、JVM前置知识1. -X、-XX含义2. JVM参数值的类型和设置方式3. 查看GC时用到的命令和JVM参数4. 查看JVM默认参数二、垃圾收集器选择-XX:UseSerialGC-XX:UseParallelGC-XX:UseParallelOldGC-XX:UseParNewGC-XX:UseConcMarkSweepGC-XX:UseG1GC三、垃圾收集器特有参数1. ParN…...

C语言经典编程题100例(61~80)

目录61、练习7-7 矩阵运算62、练习7-8 方阵循环右移63、习题6-1 分类统计字符个数64、习题6-2 使用函数求特殊a串数列和65、习题6-4 使用函数输出指定范围内的Fibonacci数66、习题6-5 使用函数验证哥德巴赫猜想67、习题6-6 使用函数输出一个整数的逆序数68、练习8-2 计算两数的…...

toxssin:一款功能强大的XSS漏洞扫描利用和Payload生成工具

关于toxssin toxssin是一款功能强大的XSS漏洞扫描利用和Payload生成工具&#xff0c;这款渗透测试工具能够帮助广大研究人员自动扫描、检测和利用跨站脚本XSS漏洞。该工具由一台HTTPS服务器组成&#xff0c;这台服务器将充当一个解释器&#xff0c;用于处理恶意JavaScript Pay…...

Keepalived与HaProxy的协调合作原理分析

Keepalived与HaProxy的协调合作原理分析keepalived与haproxy合作场景更好的理解方式协调合作中考虑的问题一、Keepalived以TCP/IP模型角度来分析&#xff1a;二、HaProxy总结&#xff1a;协调合作中考虑的问题的答案虚拟ip&#xff1a;虚拟IP技术&#xff0c;就是一个未分配给客…...

抖音如何找到博主视频推广?筛选博主要看那些数据

近年来抖音视频推广越来越成为企业宣传的热门选择&#xff0c;今天就来和大家聊聊抖音如何找到博主视频推广&#xff0c;以及几种主流的对接方式。一、什么是抖音博主视频推广?抖音博主视频推广就是通过博主的影响力和粉丝量&#xff0c;吸引用户到短视频平台进行观看相关合作…...

Win11的两个实用技巧系列之如何关闭登录密码?

Win11如何关闭登录密码?Win11关闭登录密码的两种解决方法win11是电脑更新后的全新系统&#xff0c;每次开启需要输入密码。有的用户嫌麻烦想要关闭&#xff0c;下面小编就为大家带来了关闭的方法&#xff0c;一起来看看吧有不少用户在升级或者第一次使用Win11系统的时候&#…...

润普挂卷失败之老卷宗对接NP无法获取案件信息问题排查

润普挂卷失败之老卷宗对接NP无法获取案件信息问题排查 写在最前面 根因&#xff1a;NP的dzjzzzfw与老卷宗dzjz服务用的zookeeper不是同一个&#xff0c;且老卷宗指向的zookeeper没有任何一个匹配的dzjzzzfw。仅有消费者&#xff0c;没有任何生产者&#xff0c;导致老卷宗通过…...

产品经理面试题思考及回答思路(一)

求职产品助理/经理岗位&#xff0c;转行产品岗面试真题 关于产品经理岗位能力的思考&#xff1a; 什么是产品经理&#xff1f;为什么要当/选择做产品经理&#xff1f;怎么理解产品经理&#xff1f;如何理解产品经理的价值&#xff1f;产品日常工作有哪些&#xff1f;工作流程…...

Routability-Driven Macro Placement with Embedded CNN-Based Prediction Model

Routability-Driven Macro Placement with Embedded CNN-Based Prediction Model 2019 Design, Automation & Test in Europe Conference & Exhibition (DATE) DOI: 10.23919/DATE.2019.8715126 目录Abstract一、Introduction二、PROBLEM FORMULATION AND PRELIMINARIE…...

论一个上班族如何一次性通过PMP考试

PMP是我工作后考取的一个证书。从准备到通过&#xff0c;花了大约三个月的时间。我之前在某家互联网公司从事程序员的工作&#xff0c;工作一段时间后&#xff0c;天天敲着代码&#xff0c;改着bug&#xff0c;感觉比较迷茫&#xff0c;不知道未来的发展在哪里&#xff0c;都说…...

Web前端:使用Angular CLI时的最佳实践和专业技巧

在web开发业务中&#xff0c;构建高性能的应用程序是首要因素。此外&#xff0c;用开发人员最流行的语言开发一个健壮的网站将始终为构建高功能的网站提供适当的基础网站。相比之下&#xff0c;不可否认&#xff0c;Angular CLI是建立得最好且正在成长的框架之一。Angular CLI简…...

从0到1一步一步玩转openEuler--15 openEuler使用DNF管理软件包

文章目录15.1 搜索软件包15.2 列出软件包清单15.3 显示RPM包信息15.4 安装RPM包15.5 下载软件包15.6 删除软件包DNF是一款Linux软件包管理工具&#xff0c;用于管理RPM软件包。DNF可以查询软件包信息&#xff0c;从指定软件库获取软件包&#xff0c;自动处理依赖关系以安装或卸…...

【java】Spring Boot --spring boot项目整合xxl-job

文章目录1、源码下载地址2.文档地址3.源码结构4.初始化数据库脚本5.配置调度中心xxl-job-admin5.1 修改调度中心配置文件&#xff1a;/xxl-job/xxl-job-admin/src/main/resources/application.properties5.2 启动调度中心5.3 访问调度中心管理界面6.创建执行器项目6.3 载入配置…...

视图、索引、存储过程、触发器

视图、索引、存储过程、触发器 group by补充&#xff1a; 规范来说&#xff0c;分组查询中&#xff0c;select后的字段只能是group by的字段或者是聚合函数。mysql在这有一个小优化&#xff0c;分组后如果某个字段的所有记录相同&#xff0c;同样可以select。 视图 视图是虚拟…...

ImportError: cannot import name ‘FlattenObservation‘ from ‘gym.wrappers‘ 解决方案

问题描述 今天在运行openai给出的ppo2的baseline的时候遇到了以下bug&#xff1a; File "/root/code/baselines_openai/baselines/common/cmd_util.py", line 12, in <module> from gym.wrappers import FlattenObservation, FilterObservation ImportErr…...

设计模式和设计原则回顾

设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...

【Linux】shell脚本忽略错误继续执行

在 shell 脚本中&#xff0c;可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行&#xff0c;可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令&#xff0c;并忽略错误 rm somefile…...

UE5 学习系列(三)创建和移动物体

这篇博客是该系列的第三篇&#xff0c;是在之前两篇博客的基础上展开&#xff0c;主要介绍如何在操作界面中创建和拖动物体&#xff0c;这篇博客跟随的视频链接如下&#xff1a; B 站视频&#xff1a;s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...

cf2117E

原题链接&#xff1a;https://codeforces.com/contest/2117/problem/E 题目背景&#xff1a; 给定两个数组a,b&#xff0c;可以执行多次以下操作&#xff1a;选择 i (1 < i < n - 1)&#xff0c;并设置 或&#xff0c;也可以在执行上述操作前执行一次删除任意 和 。求…...

C# 类和继承(抽象类)

抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...

【JavaWeb】Docker项目部署

引言 之前学习了Linux操作系统的常见命令&#xff0c;在Linux上安装软件&#xff0c;以及如何在Linux上部署一个单体项目&#xff0c;大多数同学都会有相同的感受&#xff0c;那就是麻烦。 核心体现在三点&#xff1a; 命令太多了&#xff0c;记不住 软件安装包名字复杂&…...

使用 SymPy 进行向量和矩阵的高级操作

在科学计算和工程领域&#xff0c;向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能&#xff0c;能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作&#xff0c;并通过具体…...

【Java学习笔记】BigInteger 和 BigDecimal 类

BigInteger 和 BigDecimal 类 二者共有的常见方法 方法功能add加subtract减multiply乘divide除 注意点&#xff1a;传参类型必须是类对象 一、BigInteger 1. 作用&#xff1a;适合保存比较大的整型数 2. 使用说明 创建BigInteger对象 传入字符串 3. 代码示例 import j…...

return this;返回的是谁

一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请&#xff0c;不同级别的经理有不同的审批权限&#xff1a; // 抽象处理者&#xff1a;审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...

处理vxe-table 表尾数据是单独一个接口,表格tableData数据更新后,需要点击两下,表尾才是正确的

修改bug思路&#xff1a; 分别把 tabledata 和 表尾相关数据 console.log() 发现 更新数据先后顺序不对 settimeout延迟查询表格接口 ——测试可行 升级↑&#xff1a;async await 等接口返回后再开始下一个接口查询 ________________________________________________________…...