Rust 基于 await、async 的异步编程和纤程、协程的实现
一、Rust 的异步编程
Rust 通过 await、async 实现了其他语言中纤程、协程的机制。下面是一个使用async和await的Rust示例代码。这个示例展示了如何异步地读取文件内容。
首先,确保你的Cargo.toml文件包含了tokio库的依赖,如下:
[dependencies]
tokio = { version = "1", features = ["full", "sync"] }
然后,你可以编写如下代码:
use tokio::fs;
use tokio::io;
use tokio::runtime;// 定义一个异步函数,用于读取文件内容
async fn read_file_content(path: &str) -> Result<String, Box<dyn std::error::Error>> {// 使用tokio的fs模块异步读取文件let file = fs::File::open(path).await?;let mut content = String::new();// 使用tokio的io模块异步读取文件内容到字符串中io::read_to_string(file, &mut content).await?;Ok(content)
}#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {let file_path = "example.txt"; // 替换为你的文件路径let content = await!(read_file_content(file_path))?; // 使用await!宏等待异步操作完成println!("File content: {}", content);// 或者使用更现代的await语法let content2 = await read_file_content(file_path)?;println!("File content (using modern await syntax): {}", content2);Ok(())
}
在这个例子中,read_file_content函数是一个异步函数,它使用tokio::fs::File::open异步地打开文件,并使用tokio::io::read_to_string异步地将文件内容读取到字符串中。main函数也是一个异步函数,它使用tokio::main宏来启动一个Tokio运行时,并调用read_file_content函数来异步读取文件内容。在main函数中,你可以看到两种使用await的方式:一种是使用await!宏(这在Tokio的旧版本中常见),另一种是直接使用await关键字(这是推荐的方式,并在Rust和Tokio的新版本中更常见)。
要运行这段代码,请确保你的项目目录中存在一个名为example.txt的文件,或者将file_path变量更改为指向实际存在的文件。然后,使用cargo build和cargo run命令来构建和运行你的程序。
请注意,异步编程在Rust中是一个相对高级的主题,需要一些时间来熟悉。此外,Tokio库可能会随着版本的更新而有所变化,因此建议查阅最新的Tokio文档以获取最准确的信息。
二、await 的意思是要阻塞等到它修饰的函数结束吗?
await 在 Rust 的异步编程中并不是阻塞等待修饰的函数结束。相反,await 允许程序在等待异步操作完成时,释放当前任务的执行权,以便调度器可以执行其他任务。这是非阻塞的,因此不会浪费任何计算资源。
具体来说,当一个 async 函数中遇到一个 await 表达式时,它会暂停当前函数的执行,并返回一个 Future 对象给调度器。调度器随后可以安排其他任务执行,而不会阻塞当前线程。一旦等待的异步操作完成(例如,I/O 操作完成或某个定时器到期),await 表达式的结果就会变得可用,并且 async 函数可以继续执行。
这种机制使得 Rust 的异步编程模型非常高效,能够充分利用系统资源,处理大量的并发任务。因此,await 并不会阻塞线程或整个程序,而是允许程序在等待异步操作时继续执行其他任务。
这里是一个简单的例子来进一步说明 await 的非阻塞特性:
use tokio::runtime;
use tokio::time;async fn say_hello_after(delay: u64) {println!("Waiting for {} seconds...", delay);time::sleep(time::Duration::from_secs(delay)).await; // 非阻塞等待println!("Hello after {} seconds!", delay);
}#[tokio::main]
async fn main() {// 启动两个并发任务,它们都会等待一段时间然后打印消息let task1 = tokio::spawn(say_hello_after(2));let task2 = tokio::spawn(say_hello_after(1));// 等待两个任务完成await!(task1);await!(task2);
}
在这个例子中,say_hello_after 函数是一个异步函数,它等待指定的秒数后打印一条消息。tokio::spawn 用于在Tokio运行时中启动新的并发任务。由于 time::sleep(...).await 是非阻塞的,所以即使 say_hello_after(2) 的延迟比 say_hello_after(1) 长,Tokio运行时仍然能够同时处理这两个任务,并在它们各自的延迟结束后打印相应的消息。
总结来说,await 使得异步编程更加直观和易于管理,同时保持了非阻塞的特性,使得程序能够高效地处理并发任务。
三、async 函数会启用一个新的线程吗?
在Rust的异步编程模型中,async函数本身并不会直接启动一个新的线程。相反,async函数定义了一个可以在未来某个时间点执行的异步计算。这个异步计算可以在当前的线程或执行器(如Tokio运行时)上调度,而不会阻塞该线程的其他工作。
Rust的异步编程是基于事件循环和协程(或称为纤程)的概念,而不是基于线程。这意味着异步函数在执行时,它们的状态会被保存起来,并在需要时恢复执行,而不会占用整个线程。这使得异步函数能够高效地处理I/O操作和其他潜在的阻塞操作,而不会浪费系统资源。
当你调用一个async函数时,它会立即返回一个Future对象,而不是立即执行函数体中的代码。这个Future对象代表了异步操作的结果,并且可以在未来的某个时间点通过await表达式来获取。
Tokio等运行时库负责调度和执行这些异步操作。它们使用非阻塞I/O和事件循环来管理多个异步任务的执行,并根据需要在线程池上调度这些任务。这意味着虽然异步操作本身不会启动新线程,但它们可以在现有的线程池中的线程上执行,从而实现高效的并发处理。
总结来说,async函数本身不会启动新的线程,而是定义了一个可以异步执行的计算。异步操作的执行是由运行时库(如Tokio)管理的,它们可能会在线程池中的线程上调度这些操作,以实现高效的并发处理。
四、异步编程必须借助 Tokio 代码库吗?
async 和 await 不是 Tokio 专门提供的功能,而是 Rust 语言本身的一部分,用于支持异步编程。Tokio 是一个 Rust 中的异步编程库,它提供了一系列用于构建高效并发和异步系统的工具和抽象。在 Tokio 中,你可以使用 async 和 await 关键字来编写异步函数和处理异步操作。
async 关键字用于声明一个函数是异步的,这意味着该函数可以包含挂起执行的操作(如网络请求或文件读写),而不会阻塞整个程序的执行。await 关键字则用于在异步函数中等待一个异步操作完成。
Tokio 库提供了一套完整的异步编程原语和工具,包括异步 I/O、定时器、并发执行等。它使得在 Rust 中编写异步代码变得更加简单和直观,通过结合 async/await 语法,你可以编写出清晰易读的异步代码,提高程序的并发性能和响应能力。
因此,虽然 async 和 await 不是 Tokio 特有的功能,但 Tokio 充分利用了这些关键字,为你提供了一个强大而灵活的异步编程框架。
相关文章:
Rust 基于 await、async 的异步编程和纤程、协程的实现
一、Rust 的异步编程 Rust 通过 await、async 实现了其他语言中纤程、协程的机制。下面是一个使用async和await的Rust示例代码。这个示例展示了如何异步地读取文件内容。 首先,确保你的Cargo.toml文件包含了tokio库的依赖,如下: [dependen…...
【进阶五】Python实现SDVRP(需求拆分)常见求解算法——差分进化算法(DE)
基于python语言,采用经典差分进化算法(DE)对 需求拆分车辆路径规划问题(SDVRP) 进行求解。 目录 往期优质资源1. 适用场景2. 代码调整3. 求解结果4. 代码片段参考 往期优质资源 经过一年多的创作,目前已经成…...
什么是神经网络?
一、什么是神经网络? 神经网络又称人工神经网络,是一种基于人脑功能模型的计算架构,因此称之为“神经”。神经网络由一组称为“节点”的处理单元组成。这些节点相互传递数据,就像大脑中的神经元相互传递电脉冲一样。 神经网络在…...
基于Python的图形用户界面设计及应用
基于Python的图形用户界面设计及应用 摘要:随着信息技术的飞速发展,图形用户界面(GUI)已成为现代软件不可或缺的一部分。Python作为一种简洁、易读且功能强大的编程语言,提供了多种GUI开发工具包,如Tkinte…...
python网络爬虫实战教学——urllib的使用(1)
文章目录 专栏导读1、前言2、urllib的使用3、发送请求3.1 urlopen3.2 request 专栏导读 ✍ 作者简介:i阿极,CSDN 数据分析领域优质创作者,专注于分享python数据分析领域知识。 ✍ 本文录入于《python网络爬虫实战教学》,本专栏针对…...
简述归并排序
归并排序 特点: 高效稳定时间复杂度最佳/平均/最差: O(N log N) 递归算法有专门的公式来计算时间复杂度 空间复杂度 O(N) 因为开辟了临时的tem_arr数组 一个静态的演示图(from leetcode) 一个动态的演示图 合并实现使用merge函数 inline void merge(v…...
HTML实现卷轴动画完整源码附注释
动画效果截图 页面的html结构代码 <!DOCTYPE html> <html> <head lang=...
sh: 1: dtc: not found
报错: bl31.bin size: 41632 u-boot-nodtb.bin size: 815816 ai_robot.dtb size: 30552 ./mkimage_uboot -E -p 0x3000 -f u-boot-ai-robot.its u-boot-ai-robot.itb sh: 1: dtc: not found ./mkimage_uboot: Cant open u-boot-ai-robot.itb.tmp: No such file …...
laravel 表单验证的 exists、unique 去除软删除字段的校验
use Illuminate\Validation\Rule; exists 去除软删除字段的校验 $validator \Validator::make($data, [phone_new > [Rule::exists(users, phone)->whereNull(deleted_at),]], [phone_new.exists > 手机号不存在,]);unique 去除软删除字段的校验 // 新增 email>r…...
【PHP + 代码审计】函数详解2.0
🍬 博主介绍👨🎓 博主介绍:大家好,我是 hacker-routing ,很高兴认识大家~ ✨主攻领域:【渗透领域】【应急响应】 【Java、PHP】 【VulnHub靶场复现】【面试分析】 🎉点赞➕评论➕收…...
宠物智能喂食机方案设计
我们都知道,现如今养宠物的人群已经很多了,主要是青年人居多,他们在独自漂泊的在外的工作,免不了情感泛滥,养一些小动物也是在预料之中。但由于工作或者其他各种因数,养宠人不可时时刻刻在家,对…...
测试直播打赏需要考虑哪些测试要点?
1.功能测试: 1、检查打赏功能是否正确 :检查打赏操作是否可以正常进行 2、 赞赏余额是否正确: 检查赞赏者和被赞赏者的余额是否正确 3、赞赏交易记录是否正确: 检查赞赏者和被赞赏者的交易记录是否正确; 4、检查赞…...
Python练习(续)
练习1:用户登录注册案例 import sysidname {test:123456}print(""" 英雄联盟商城登录界面~ * ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~1. 用户登录2. 新用户注册3. 退出系统~ * ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~ …...
发布镜像到阿里云仓库
发布上一篇Dockerfile实战-自定义的centos镜像。 1、登录阿里云 2、找到容器镜像服务 3、创建命令空间 4、创建镜像仓库 5、点击进入这个镜像仓库,可以看到所有的信息 6、根据操作指南测试推送发布 6.1登录阿里云 [rootzhoujunru home]# docker login --usernam…...
web蓝桥杯真题:灯的颜色变化
代码及注释: // TODO:完善此函数 显示红色颜色的灯 function red() { //将红色图片元素display显示出来,其他隐藏document.querySelector(#defaultlight).style.display nonedocument.querySelector(#redlight).style.display inline-b…...
通过docker容器安装zabbix6.4.12图文详解(监控服务器docker容器)
目录 一、相关环境及镜像二、zabbix-server服务端部署1.使用docker创建zabbix-server服务端(1). 创建专用于Zabbix组件容器的网络(2). 启动空的MySQL服务器实例(3). 启动Zabbix Java网关实例(4). 启动Zabbix服务器实例并将实例与创建的MySQL服务器实例链接(5). 启动Zabbix Web界…...
算法打卡day21|回溯法篇01|理论知识,Leetcode 77.组合
回溯法理论知识 回溯法也可以叫做回溯搜索法,它是一种搜索的方式。回溯是递归的副产品,只要有递归就会有回溯。所以回溯函数也就是递归函数,指的都是一个函数。 回溯法的效率 回溯法并不是什么高效的算法。因为回溯的本质是穷举,…...
C++ 输入输出
输入 1.1 cin >> str; 遇到“空格”、“TAB”、“回车”就停止 string str; cin >> str;1.2 getline(cin, str) 可用于输入一行数据,遇到空格不会停止,读入string字符中 便于读取一行一行的数据 while(getline(cin, str)){if(str "EN…...
FPGA高端项目:FPGA基于GS2971+GS2972架构的SDI视频收发+HLS图像缩放+多路视频拼接,提供4套工程源码和技术支持
目录 1、前言免责声明 2、相关方案推荐本博主所有FPGA工程项目-->汇总目录本博已有的 SDI 编解码方案本方案的SDI接收发送本方案的SDI接收图像缩放应用本方案的SDI接收纯verilog图像缩放纯verilog多路视频拼接应用本方案的SDI接收OSD动态字符叠加输出应用本方案的SDI接收HLS…...
【gpt实践】50个提升工作效率的GPT指令
收集整理了50个工作不同场景中可能会用到的gpt指令,希望对大家有帮助。 1. 用「532规则」定制月度宣传规划 提示:“对于我的 [产品/服务] 在 [社交媒体平台上 ]定位 [我的目标受众]”,使用 5-3-2 规则制定 1 个月的社交媒体内容计划。” Pro…...
别再只盯着论文了!手把手教你用PyTorch复现3个经典医学图像融合模型(附完整代码)
从理论到实践:PyTorch复现医学图像融合模型的实战指南 医学图像融合技术正逐渐成为临床诊断和科研分析的重要工具。不同于单纯的理论探讨或论文整理,本文将带您深入三个经典模型的代码实现细节,让抽象的网络结构变得触手可及。无论您是刚入门…...
3分钟搞定!为Word添加APA第7版引用模板的终极指南
3分钟搞定!为Word添加APA第7版引用模板的终极指南 【免费下载链接】APA-7th-Edition Microsoft Word XSD for generating APA 7th edition references 项目地址: https://gitcode.com/gh_mirrors/ap/APA-7th-Edition 还在为学术论文的APA格式烦恼吗ÿ…...
Qwen3-14B企业级API网关设计:实现高可用、可扩展的AI服务
Qwen3-14B企业级API网关设计:实现高可用、可扩展的AI服务 1. 企业级AI服务的挑战与机遇 在数字化转型浪潮中,大型语言模型如Qwen3-14B正成为企业智能化转型的核心引擎。然而,直接将模型暴露给业务系统会面临诸多挑战:突发流量可…...
Python 3.12 Special Attribute - 28 - __match_args__
Python 3.12 Special Attribute - __match_args____match_args__ 是 Python 3.10 引入的一个 类属性 ,用于支持 结构模式匹配(Structural Pattern Matching) 中的 类模式 。它定义了类实例在 match 语句中按 位置 解构时,属性与…...
Path of Building 2:流放之路2角色规划器的3大核心功能与5步上手指南
Path of Building 2:流放之路2角色规划器的3大核心功能与5步上手指南 【免费下载链接】PathOfBuilding-PoE2 项目地址: https://gitcode.com/GitHub_Trending/pa/PathOfBuilding-PoE2 还在为《流放之路2》复杂的天赋树和装备搭配而困惑吗?Path o…...
【AGI决策能力评估权威框架】:2024全球7大实验室实测数据+3层可验证指标体系首次公开
第一章:AGI的规划与决策能力评估 2026奇点智能技术大会(https://ml-summit.org) AGI的规划与决策能力并非单一维度指标,而是融合目标分解、状态建模、多步推理、反事实评估与实时适应的复合认知过程。当前主流评估框架已从静态任务准确率转向动态环境下…...
LeetCodeHot100 2. 两数相加 思路JavaScript版本代码
题目思路以题目提供的例子为例来进行思考分别将两个数倒过来计算,类似如图,结合链表其实非常方便。创建一个新的虚拟链表newlist存储计算结果,tail指向该链表的末尾。首先计算l1和l2的首位,25 7,更新newlist的tail的值为7&#x…...
手把手教你用STM32的FSMC驱动AD7606(附完整电路图与代码)
STM32与AD7606高速数据采集系统实战指南 在工业自动化、电力监测和医疗设备等领域,高精度多通道数据采集系统扮演着关键角色。AD7606作为一款16位8通道同步采样ADC,配合STM32的FSMC接口,能够构建出性能优异的数据采集解决方案。本文将深入探讨…...
从嵌入式春招到秋招:我用C语言刷动态规划(背包问题)的实战心得
从嵌入式春招到秋招:我用C语言刷动态规划(背包问题)的实战心得 去年春天,当我第一次打开某大厂的在线笔试系统时,手心里全是汗。作为嵌入式专业的学生,我本以为笔试会偏向硬件和底层开发,没想到…...
AGI平民化接入实战手册(SITS2026现场闭门报告首次公开)
第一章:SITS2026专家:AGI的民主化访问 2026奇点智能技术大会(https://ml-summit.org) 从封闭模型到开放协议 AGI能力正加速脱离专有云服务与高门槛API调用范式,转向基于轻量级推理引擎、可验证提示合约和联邦式知识更新的开放基础设施。SIT…...
