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

Rust 基于 await、async 的异步编程和纤程、协程的实现

一、Rust 的异步编程

Rust 通过 await、async 实现了其他语言中纤程、协程的机制。下面是一个使用asyncawait的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 buildcargo 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示例代码。这个示例展示了如何异步地读取文件内容。 首先&#xff0c;确保你的Cargo.toml文件包含了tokio库的依赖&#xff0c;如下&#xff1a; [dependen…...

【进阶五】Python实现SDVRP(需求拆分)常见求解算法——差分进化算法(DE)

基于python语言&#xff0c;采用经典差分进化算法&#xff08;DE&#xff09;对 需求拆分车辆路径规划问题&#xff08;SDVRP&#xff09; 进行求解。 目录 往期优质资源1. 适用场景2. 代码调整3. 求解结果4. 代码片段参考 往期优质资源 经过一年多的创作&#xff0c;目前已经成…...

什么是神经网络?

一、什么是神经网络&#xff1f; 神经网络又称人工神经网络&#xff0c;是一种基于人脑功能模型的计算架构&#xff0c;因此称之为“神经”。神经网络由一组称为“节点”的处理单元组成。这些节点相互传递数据&#xff0c;就像大脑中的神经元相互传递电脉冲一样。 神经网络在…...

基于Python的图形用户界面设计及应用

基于Python的图形用户界面设计及应用 摘要&#xff1a;随着信息技术的飞速发展&#xff0c;图形用户界面&#xff08;GUI&#xff09;已成为现代软件不可或缺的一部分。Python作为一种简洁、易读且功能强大的编程语言&#xff0c;提供了多种GUI开发工具包&#xff0c;如Tkinte…...

python网络爬虫实战教学——urllib的使用(1)

文章目录 专栏导读1、前言2、urllib的使用3、发送请求3.1 urlopen3.2 request 专栏导读 ✍ 作者简介&#xff1a;i阿极&#xff0c;CSDN 数据分析领域优质创作者&#xff0c;专注于分享python数据分析领域知识。 ✍ 本文录入于《python网络爬虫实战教学》&#xff0c;本专栏针对…...

简述归并排序

归并排序 特点&#xff1a; 高效稳定时间复杂度最佳/平均/最差&#xff1a; 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

报错&#xff1a; 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

&#x1f36c; 博主介绍&#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 hacker-routing &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【应急响应】 【Java、PHP】 【VulnHub靶场复现】【面试分析】 &#x1f389;点赞➕评论➕收…...

宠物智能喂食机方案设计

我们都知道&#xff0c;现如今养宠物的人群已经很多了&#xff0c;主要是青年人居多&#xff0c;他们在独自漂泊的在外的工作&#xff0c;免不了情感泛滥&#xff0c;养一些小动物也是在预料之中。但由于工作或者其他各种因数&#xff0c;养宠人不可时时刻刻在家&#xff0c;对…...

测试直播打赏需要考虑哪些测试要点?

1.功能测试&#xff1a; 1、检查打赏功能是否正确 &#xff1a;检查打赏操作是否可以正常进行 2、 赞赏余额是否正确&#xff1a; 检查赞赏者和被赞赏者的余额是否正确 3、赞赏交易记录是否正确&#xff1a; 检查赞赏者和被赞赏者的交易记录是否正确&#xff1b; 4、检查赞…...

Python练习(续)

练习1:用户登录注册案例 import sysidname {test:123456}print(""" 英雄联盟商城登录界面~ * ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~1. 用户登录2. 新用户注册3. 退出系统~ * ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~ * ~ …...

发布镜像到阿里云仓库

发布上一篇Dockerfile实战-自定义的centos镜像。 1、登录阿里云 2、找到容器镜像服务 3、创建命令空间 4、创建镜像仓库 5、点击进入这个镜像仓库&#xff0c;可以看到所有的信息 6、根据操作指南测试推送发布 6.1登录阿里云 [rootzhoujunru home]# docker login --usernam…...

web蓝桥杯真题:灯的颜色变化

代码及注释&#xff1a; // TODO&#xff1a;完善此函数 显示红色颜色的灯 function red() { //将红色图片元素display显示出来&#xff0c;其他隐藏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.组合

回溯法理论知识 回溯法也可以叫做回溯搜索法&#xff0c;它是一种搜索的方式。回溯是递归的副产品&#xff0c;只要有递归就会有回溯。所以回溯函数也就是递归函数&#xff0c;指的都是一个函数。 回溯法的效率 回溯法并不是什么高效的算法。因为回溯的本质是穷举&#xff0c;…...

C++ 输入输出

输入 1.1 cin >> str; 遇到“空格”、“TAB”、“回车”就停止 string str; cin >> str;1.2 getline(cin, str) 可用于输入一行数据&#xff0c;遇到空格不会停止&#xff0c;读入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指令&#xff0c;希望对大家有帮助。 1. 用「532规则」定制月度宣传规划 提示&#xff1a;“对于我的 [产品/服务] 在 [社交媒体平台上 ]定位 [我的目标受众]”&#xff0c;使用 5-3-2 规则制定 1 个月的社交媒体内容计划。” Pro…...

网络编程(Modbus进阶)

思维导图 Modbus RTU&#xff08;先学一点理论&#xff09; 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议&#xff0c;由 Modicon 公司&#xff08;现施耐德电气&#xff09;于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...

Flask RESTful 示例

目录 1. 环境准备2. 安装依赖3. 修改main.py4. 运行应用5. API使用示例获取所有任务获取单个任务创建新任务更新任务删除任务 中文乱码问题&#xff1a; 下面创建一个简单的Flask RESTful API示例。首先&#xff0c;我们需要创建环境&#xff0c;安装必要的依赖&#xff0c;然后…...

Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动

一、前言说明 在2011版本的gb28181协议中&#xff0c;拉取视频流只要求udp方式&#xff0c;从2016开始要求新增支持tcp被动和tcp主动两种方式&#xff0c;udp理论上会丢包的&#xff0c;所以实际使用过程可能会出现画面花屏的情况&#xff0c;而tcp肯定不丢包&#xff0c;起码…...

蓝桥杯 2024 15届国赛 A组 儿童节快乐

P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡&#xff0c;轻快的音乐在耳边持续回荡&#xff0c;小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下&#xff0c;六一来了。 今天是六一儿童节&#xff0c;小蓝老师为了让大家在节…...

ElasticSearch搜索引擎之倒排索引及其底层算法

文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...

深度学习习题2

1.如果增加神经网络的宽度&#xff0c;精确度会增加到一个特定阈值后&#xff0c;便开始降低。造成这一现象的可能原因是什么&#xff1f; A、即使增加卷积核的数量&#xff0c;只有少部分的核会被用作预测 B、当卷积核数量增加时&#xff0c;神经网络的预测能力会降低 C、当卷…...

HubSpot推出与ChatGPT的深度集成引发兴奋与担忧

上周三&#xff0c;HubSpot宣布已构建与ChatGPT的深度集成&#xff0c;这一消息在HubSpot用户和营销技术观察者中引发了极大的兴奋&#xff0c;但同时也存在一些关于数据安全的担忧。 许多网络声音声称&#xff0c;这对SaaS应用程序和人工智能而言是一场范式转变。 但向任何技…...

HTML前端开发:JavaScript 获取元素方法详解

作为前端开发者&#xff0c;高效获取 DOM 元素是必备技能。以下是 JS 中核心的获取元素方法&#xff0c;分为两大系列&#xff1a; 一、getElementBy... 系列 传统方法&#xff0c;直接通过 DOM 接口访问&#xff0c;返回动态集合&#xff08;元素变化会实时更新&#xff09;。…...

Python学习(8) ----- Python的类与对象

Python 中的类&#xff08;Class&#xff09;与对象&#xff08;Object&#xff09;是面向对象编程&#xff08;OOP&#xff09;的核心。我们可以通过“类是模板&#xff0c;对象是实例”来理解它们的关系。 &#x1f9f1; 一句话理解&#xff1a; 类就像“图纸”&#xff0c;对…...