rust学习(tokio协程分析一)

news/发布时间2024/9/20 6:07:33

代码:

async fn doAsyncPrint(v:u32) {println!("start doAsyncPrint,v is {},tid is {:?}",v,system::myTid());//thread::sleep(Duration::from_secs(1));time::sleep(Duration::from_secs(10)).await;println!("end,v is {},tid is {:?}",v,system::myTid());
}fn testCoroutine3() {println!("testCoroutine3 start");let array = Arc::new(BlockingQueue::<u32>::new());let arrayclosure1 = array.clone();thread::spawn(move|| {let mut count:u32 = 0;loop {//println!("thread start,count is {}",count);arrayclosure1.putLast(count);count += 1;thread::sleep(Duration::from_secs(1));}});let arrayclosure2 = array.clone();thread::spawn(move ||{let rt = tokio::runtime::Builder::new_current_thread().enable_all().build().unwrap();let guard1 = rt.enter();println!("coroutine start,tid is {:?}", system::myTid());loop {let v = arrayclosure2.takeFirst();//println!("coroutine trace1,v is {}",v);tokio::spawn(doAsyncPrint(v));}}).join();
}

代码运行时会直接卡住,这个和协程的原理有关:

1.let rt = tokio::runtime::Builder::new_current_thread().enable_all().build().unwrap();

这里创建一个协程的runtime,注意:这里协程是跑在当前的线程中

2.let v = arrayclosure2.takeFirst();

从blocking队列中获取数据,注意这个blocking队列使用了mutex和condvar,所以当condvar卡住的时候,实际上是整个线程直接卡住,由于协程只是在线程中来回切换调用栈,所以协程中所有的等待处理实际上都是切换调用栈,但是这个condvar不是切换调用栈,所以就会卡住。

3.tokio::spawn(doAsyncPrint(v));

doAsyncPrint一直没有被调用

方案:

将new_current_thread改成new_multi_thread

代码如下:

async fn doAsyncPrint(v:u32) {println!("start doAsyncPrint,v is {},tid is {:?}",v,system::myTid());//thread::sleep(Duration::from_secs(1));time::sleep(Duration::from_secs(10)).await;println!("end,v is {},tid is {:?}",v,system::myTid());
}thread::spawn(move ||{let rt = tokio::runtime::Builder::new_multi_thread().worker_threads(1).enable_all().build().unwrap();let guard1 = rt.enter();println!("coroutine start,tid is {:?}", system::myTid());loop {let v = arrayclosure2.takeFirst();//println!("coroutine trace1,v is {}",v);tokio::spawn(doAsyncPrint(v));}}).join();

这样实际上协程的runtime会创建线程,让协程跑在这些线程上,如上述代码,我们通过worker_threads创建了一个线程,所有的协程都会跑在这个线程上。

我们看一下运行结果:

你会发现,所有的协程都跑在了thread4上,我们看一下代码:

async fn doAsyncPrint(v:u32) {println!("start doAsyncPrint,v is {},tid is {:?}",v,system::myTid());//thread::sleep(Duration::from_secs(1));time::sleep(Duration::from_secs(10)).await;println!("end,v is {},tid is {:?}",v,system::myTid());
}

发现没有,一开始的时候连续打印了多个“start doAsyncPrint”,但是没有打印“end,v is ....”这个是为啥咧?原因就在time::sleep这个函数(tokio::time::sleep),实际上,这个sleep没有真让线程sleep,而且直接切换调用栈,切换到下一个函数上,所以一开始我们可以看到连续的“start doAsyncPrint”。

协程的使用还是比较要当心的,所有操作io操作啥估计都要使用tokio的接口,否者就会导致卡住。例如上面的代码,如果改成thread::sleep的话,就会直接卡住线程,输出结果就如下:

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

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

相关文章

使用正则表达式的SqlServer Check约束实例

有表如下&#xff1b;会员表&#xff0c;第一个字段是会员编号&#xff0c;varchar(24)类型&#xff1b;第二个字段是单位名称&#xff1b; 现在插入一条记录&#xff0c;会员编号为abcd&#xff1b;插入了&#xff1b; 下面要添加一个约束&#xff0c;会员编号字段只能为数字的…

适配器模式 详解 设计模式

适配器模式 适配器模式是一种结构型设计模式&#xff0c;其主要作用是解决两个不兼容接口之间的兼容性问题。适配器模式通过引入一个适配器来将一个类的接口转换成客户端所期望的另一个接口&#xff0c;从而让原本由于接口不匹配而无法协同工作的类能够协同工作。 结构 适配…

【自然语言处理】NLP入门(一):1、正则表达式与Python中的实现(1):字符串构造、字符串截取

文章目录 一、前言二、正则表达式与Python中的实现1. 字符串构造a. 使用str函数b. 单引号或双引号构造字符串c. 单双引号构造字符串的特殊用法d. 三重引号字符串e. 典例 2. 字符串截取a. 索引b. 切片c. 注意事项 一、前言 语言是一种使用具有共同处理规则的沟通指令的广义概念&…

用html编写的小广告板

用html编写的小广告板 相关代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</tit…

类加载的基本流程

⭐ 作者&#xff1a;小胡_不糊涂 &#x1f331; 作者主页&#xff1a;小胡_不糊涂的个人主页 &#x1f4c0; 收录专栏&#xff1a;JavaEE &#x1f496; 持续更文&#xff0c;关注博主少走弯路&#xff0c;谢谢大家支持 &#x1f496; 类加载 1. 加载2. 验证3. 准备4. 解析5. 初…

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

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

JVM运行时数据区——虚拟机栈

文章目录 1、虚拟机栈概述1.1、StackOverflowError1.2、OOM异常 2、栈的存储单位3、局部变量表3.1、局部变量表简介3.2、Slot 4、操作数栈5、栈顶缓存技术6、动态链接7、方法的调用7.1、方法调用的分类7.2、虚方法与非虚方法7.3、关于invokedynamic指令7.4、方法重写的本质7.5、…

【Django】执行查询—跨关系查询中的跨多值关联问题

跨多值查询 跨越 ManyToManyField 或反查 ForeignKey &#xff08;例如从 Blog 到 Entry &#xff09;时&#xff0c;对多个属性进行过滤会产生这样的问题&#xff1a;是否要求每个属性都在同一个相关对象中重合。 filter() 先看filter()&#xff0c;通过一个例子看&#xf…

C语言 vs Rust应该学习哪个?

C语言 vs Rust应该学习哪个&#xff1f; 在开始前我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「C语言的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全部无偿共享给大家&#xff01;&#xff01;&am…

Qt应用软件【测试篇】vargrid内存检查工具

文章目录 vargrid介绍vargrid官网vargrid安装常用命令Valgrind的主要命令vargrid介绍 Valgrind是一个用于构建动态分析工具的框架,能自动检测许多内存管理和线程错误,并详细分析程序性能。Valgrind发行版包括七个成熟工具:内存错误检测器、两个线程错误检测器、缓存和分支预…

socket套接字

前言 两个应用程序如果需要进行通讯最基本的一个前提就是能够唯一的标示一个进程&#xff0c;我们知道IP层的ip地址可以唯一标示主机&#xff0c;而TCP层协议和端口号可以唯一标示主机的一个进程&#xff0c;这样我们可以利用ip地址&#xff0b;协议&#xff0b;端口号唯一标示…

工厂生产效率如何提升?这8个重点你不得不看!

企业的竞争本质上就是效率与成本的竞争&#xff08;当然是保证产品质量的前提下&#xff09;&#xff0c;如何持续不断地提高生产效率是企业永续发展的关键问题&#xff0c;提高生产效率也是降低制造成本的根本途径。 当然&#xff0c;我们必须严格根据工艺标准来操作&#xf…

docker存储驱动

目录 一、写时复制和用时分配 二、联合文件系统 2.1、aufs ​编辑 2.2、分层的问题 2.3、overlay 2.4 文件系统区别 三、容器跑httpd案例 3.1、案例1&#xff1a;端口映射 3.2、案例2&#xff1a;制作httpd应用镜像 3.3、案例3&#xff1a;docker数据卷挂载 3.4、案…

探索数据结构:解锁计算世界的密码

✨✨ 欢迎大家来到贝蒂大讲堂✨✨ &#x1f388;&#x1f388;养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; 所属专栏&#xff1a;数据结构与算法 贝蒂的主页&#xff1a;Betty‘s blog 前言 随着应用程序变得越来越复杂和数据越来越丰富&#xff0c;几百万、…

继承-学习2

this关键字&#xff1a;指向调用该方法的对象&#xff0c;一般我们是在当前类中使用this关键字&#xff0c;所以我们常说代表本类对象的引用 super关键字&#xff1a;代表父类存储空间的标识(可看作父类对象的引用) 父类&#xff1a; package ven;public class Fu {//父类成员…

细嗦MySQL三大日志

文章目录 三大日志&#xff1a;binlog&#xff08;归档日志&#xff09;、redo log&#xff08;重做日志&#xff09;、undo log&#xff08;回滚日志&#xff09;redo log刷盘机制日志文件组 binlog记录格式写入机制 两阶段提交undo log提供回滚操作提供MVCC&#xff08;多版本…

SQL-Labs靶场“46-50”关通关教程

君衍. 一、四十六关 ORDER BY数字型注入1、源码分析2、rand()盲注3、if语句盲注4、时间盲注5、报错注入6、Limit注入 二、四十七关 ORDER BY单引号报错注入1、源码分析2、报错注入3、时间盲注 三、四十八关 ODRER BY数字型盲注1、源码分析2、rand()盲注3、if语句盲注4、时间盲注…

Java进阶(锁)——锁的升级,synchronized与lock锁区别

目录 引出Java中锁升级synchronized与lock锁区别 缓存三兄弟&#xff1a;缓存击穿、穿透、雪崩缓存击穿缓存穿透缓存雪崩 总结 引出 Java进阶&#xff08;锁&#xff09;——锁的升级&#xff0c;synchronized与lock锁区别 Java中锁升级 看一段代码&#xff1a; public class…

Windows 10 合并磁盘分区 (G and H)

Windows 10 合并磁盘分区 [G and H] 1. 设备和驱动器2. 计算机 -> 管理 -> 存储 -> 磁盘管理3. 删除卷4. 新建简单卷5. 设备和驱动器References 1. 设备和驱动器 2. 计算机 -> 管理 -> 存储 -> 磁盘管理 3. 删除卷 H: -> right-click -> 删除卷 H: 变…

消息中间件篇之RabbitMQ-消息不丢失

一、生产者确认机制 RabbitMQ提供了publisher confirm机制来避免消息发送到MQ过程中丢失。消息发送到MQ以后&#xff0c;会返回一个结果给发送者&#xff0c;表示消息是否处理成功。 当消息没有到交换机就失败了&#xff0c;就会返回publish-confirm。当消息没有到达MQ时&…
推荐文章