rust学习(tokio future分析)

自己编写一个impl future来看一下Tokio的是如何实现的。

第一步:

代码:

struct TExecuteTask {count:u32
}impl Future for TExecuteTask {type Output = ();fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {println!("future require");if self.count == 2 {return Ready(());}unsafe {self.get_unchecked_mut().count += 1;}Pending}
}pub fn test1() {let v = TExecuteTask{count:0};let rt = tokio::runtime::Builder::new_multi_thread().enable_all().build().unwrap();println!("test trace1");rt.block_on(v);println!("test trace2");
}

运行结果:

貌似调用block_on之后会回调一次future的poll,如果这个时候还没有计算出结果,那就直接卡死了,所以需要找个地方能唤醒。

第二步:

原来代码上添加上wake

impl Future for TExecuteTask {type Output = ();fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {println!("future require");let mut v = self.core.lock().unwrap();v.waker = Some(cx.waker().clone());Pending}
}pub fn test1() {let waker: Arc<Mutex<TExecuteTaskCore>> = Arc::new(Mutex::new(TExecuteTaskCore {waker:None}));let task: TExecuteTask = TExecuteTask {core:waker.clone()};let rt = tokio::runtime::Builder::new_multi_thread().enable_all().build().unwrap();let closure1 = waker.clone();thread::spawn(move|| {thread::sleep(Duration::from_secs(1));let mut core: std::sync::MutexGuard<'_, TExecuteTaskCore> = closure1.lock().unwrap();if let Some(waker) = core.waker.take() {println!("detect future is ready, wakeup the future task to executor.");waker.wake()    // wakeup the future task to executor.}});println!("test trace1");rt.block_on(task);println!("test trace2");
}

关键是在poll返回pending的时候,获取waker。然后等计算完成后再wake一下哈哈。

然后结果呢:

还是卡住了。。。这个是为啥呢?原来是我poll的代码有问题,无论如何处理都是返回pending..

所以从目前的试验来看有如下结论:

1.当调用block_on的时候,会直接调用一次future的poll确认是否运算结束。

2.当调用waker.wake的时候貌似还会调用一次poll确认是否运算结束。

所以我们现在要加一个标志位来表示运算结束,这样block_on应该就能正常走下去了吧。

第三步:

impl Future for TExecuteTask {type Output = ();fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {println!("future require");let mut v = self.core.lock().unwrap();if v.complete == true {return Ready(())}v.waker = Some(cx.waker().clone());Pending}
}pub fn test1() {let waker: Arc<Mutex<TExecuteTaskCore>> = Arc::new(Mutex::new(TExecuteTaskCore {waker:None,complete:false}));let task: TExecuteTask = TExecuteTask {core:waker.clone()};let rt = tokio::runtime::Builder::new_multi_thread().enable_all().build().unwrap();let closure1 = waker.clone();thread::spawn(move|| {thread::sleep(Duration::from_secs(1));let mut core: std::sync::MutexGuard<'_, TExecuteTaskCore> = closure1.lock().unwrap();if let Some(waker) = core.waker.take() {println!("detect future is ready, wakeup the future task to executor.");core.complete = true;waker.wake()    // wakeup the future task to executor.}});println!("test trace1");rt.block_on(task);println!("test trace2");
}

添加了一个complete标志运算是否结束。

运算完成后,complete赋值为true,再尝试wake一下等待线程(协程?)

poll中也添加了complete判断,如果为true的话,直接返回Ready,然后我们看一下运行结果:

运行结束~~。哈哈。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/721197.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

「优选算法刷题」:字符串相乘

一、题目 给定两个以字符串形式表示的非负整数 num1 和 num2&#xff0c;返回 num1 和 num2 的乘积&#xff0c;它们的乘积也表示为字符串形式。 注意&#xff1a;不能使用任何内置的 BigInteger 库或直接将输入转换为整数。 示例 1: 输入: num1 "2", num2 &quo…

AI大预言模型——ChatGPT与AI绘图及论文高效写作

原文链接&#xff1a;AI大预言模型——ChatGPT与AI绘图及论文高效写作 2023年随着OpenAI开发者大会的召开&#xff0c;最重磅更新当属GPTs&#xff0c;多模态API&#xff0c;未来自定义专属的GPT。微软创始人比尔盖茨称ChatGPT的出现有着重大历史意义&#xff0c;不亚于互联网…

03:大数据与Hadoop|分布式文件系统|分布式Hadoop集群

大数据与Hadoop&#xff5c;分布式文件系统&#xff5c;分布式Hadoop集群 Hadoop部署Hadoop HDFS分布式文件系统HDFS部署步骤一&#xff1a;环境准备HDFS配置文件 查官方手册配置Hadoop集群 日志与排错 mapreduce 分布式离线计算框架YARN集群资源管理系统步骤一&#xff1a;安装…

Java已死?大学生还有必要学习Java吗【底部明信片,添加可进大学生求职社群】

目录 1. Java的历史与底蕴 2. 企业级应用的稳定性 3. Android应用开发 4. 大数据和云计算 5. 补充现代技术栈 6. Java生态系统的完备性 在技术的迅速演进中&#xff0c;有人开始质疑传统编程语言的地位&#xff0c;其中Java也未能幸免。然而&#xff0c;尽管一些人宣称“…

安卓开发:计时器

一、新建模块 二、填写应用名称和模块名称 三、选择模块&#xff0c;Next 四、可以保持不变&#xff0c;Finish 五、相关目录文件 六、相关知识 七、&#xff1f;

基本设计模式

单例模式 ES5 function Duck1(name:string){this.namenamethis.instancenull }Duck1.prototype.getNamefunction(){console.log(this.name) }Duck1.getInstancefunction(name:string){if(!this.instance){this.instance new Duck1(name)} } const aDuck1.getInstance(a) const…

PyTorch深度学习实战(38)——StyleGAN详解与实现

PyTorch深度学习实战&#xff08;38&#xff09;——StyleGAN详解与实现 0. 前言1. StyleGAN1.1 模型介绍1.2 模型策略分析 2. 实现 StyleGAN2.1 生成图像2.2 风格迁移 小结系列链接 0. 前言 StyleGAN (Style-Generative Adversarial Networks) 是生成对抗网络 (Generative Ad…

电商运营神器:如何利用数据API进行市场分析

在电子商务领域&#xff0c;市场分析是至关重要的一环。利用数据API进行市场分析可以帮助电商运营者洞察市场趋势、优化营销策略、提高用户满意度&#xff0c;并最终增加销售额。以下是如何利用数据API进行市场分析的一些关键步骤和策略&#xff1a; 获取市场数据 首先&#…

手搓反激电源 | 五、反激高频变压器的设计与计算

手搓反激电源 | 五、反激高频变压器的设计与计算 先上干货&#xff0c;变压器设计规格书 千里之行,积于跬步,万里之船,成于罗盘 A journey of thousands of miles accumulates in steps, and the ship of thousands of miles becomes a compass 反激式变换操作 反激式变换器的…

Java并发编程—final关键字

基本使用 修饰类 当某个类被修饰为 final&#xff0c;就表明此类不能被继承。 注意&#xff1a;final 中所有方法都隐式为 final&#xff0c;所以给 final 类中任何方法前加 final 都是没意义的 补充&#xff1a;如果想拓展一个 final 类怎么办&#xff1f;比如我们想写个 My…

基于springboot的教师工作量管理系统论文

教师工作量管理系统 摘要 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实施在技术上已逐步成熟。本文介绍了教师工作量管理系统的开发全过程。通过分析教师工作量管理系统管理的不足&#xff0c;创建了一个计算机管理教师工作量管理系统的方案。文章…

Ambari动态给YARN分配计算节点

1.前言 YARN可用的计算节点数量并不总是等于 Hadoop集群节点数量&#xff0c;可以根据业务需求分配 YARN计算节点数量。 这里首先介绍一些前置知识&#xff1a; YARN中 ResourceManager 和 NodeManager是两个核心组件&#xff0c;其中 ResourceManager负责集群资源的统一管理…

C语言指针详解进阶2

函数指针数组 数组是一个存放相同类型数据的存储空间&#xff0c;那我们已经学习了指针数组&#xff0c; 比如&#xff1a; int *arr[10]; //数组的每个元素是int 那要把函数的地址存到一个数组中&#xff0c;那这个数组就叫 函数指针数组 &#xff0c;那函数指针的数组如何定…

C++模拟揭秘刘谦魔术,领略数学的魅力

新的一年又开始了&#xff0c;大家新年好呀~。在这我想问大家一个问题&#xff0c;有没有同学看了联欢晚会上刘谦的魔术呢&#xff1f; 这个节目还挺有意思的&#xff0c;它最出彩的不是魔术本身&#xff0c;而是小尼老师“念错咒语”而导致他手里的排没有拼在一起&#xff0c;…

BUUCTF------[HCTF 2018]WarmUp

开局一个表情&#xff0c;源代码发现source.php <?phphighlight_file(__FILE__);class emmm{public static function checkFile(&$page){$whitelist ["source">"source.php","hint">"hint.php"];if (! isset($page) |…

06_netdev网卡设备内核模块

01_basicLinux内核模块-CSDN博客文章浏览阅读315次&#xff0c;点赞3次&#xff0c;收藏3次。环境IDubuntuMakefilemodules:clean:basic.creturn 0;运行效果。https://blog.csdn.net/m0_37132481/article/details/136157384my_netdev.c #include <linux/kernel.h> #incl…

基于springboot的大学生就业招聘系统的设计与实现论文

大学生就业招聘系统的设计与实现 摘要 随着信息互联网信息的飞速发展&#xff0c;大学生就业成为一个难题&#xff0c;好多公司都舍不得培养人才&#xff0c;只想要一专多能之人才&#xff0c;不愿是承担社会的责任&#xff0c;针对这个问题开发一个专门适应大学生就业招聘的网…

ChatGPT引领的AI面试攻略系列:cuda和tensorRT

系列文章目录 cuda和tensorRT&#xff08;本文&#xff09;AI全栈工程师 文章目录 系列文章目录一、前言二、面试题1. CUDA编程基础2. CUDA编程进阶3. 性能优化4. TensorRT基础5. TensorRT进阶6. 实际应用与案例分析7. 编程与代码实践8. 高级话题与趋势 一、前言 随着人工智能…

谈谈mysql 的日志?binlog 和 redo log 有什么区别?

谈谈mysql 的日志? MySQL数据库中有多种日志&#xff0c;其中最重要的是二进制日志&#xff08;binlog&#xff09;、重做日志&#xff08;redo log&#xff09;和回滚日志&#xff08;undo log&#xff09;。这些日志在数据库操作中起着至关重要的作用&#xff0c;不仅保证了…

大部分人只有在工作几年后才知道什么是程序员

在大学 大学时期的我们&#xff0c;有几个从大一就开始好好学习&#xff0c;立志考研的&#xff1f;大多数人都只是在“享受大学生活”&#xff0c;就连选择计算机专业都是别人推荐的&#xff0c;根本不知道将来毕业会干啥。在我们的印象中&#xff0c;程序员就是一个模糊的名…