Tokio强大的Rust异步框架

一、简介

异步是现在编写高性能应用的核心要素之一,很多语言都已经纷纷加入异步的特效。C#应该是最先做出响应的语言。连微软这位软件大佬都非常重视异步,可见异步编程重要性。

在Rust中同样支持异步编程,只不过一般我们不会使用Rust官方,而是使用第三方依赖Tokio。

二、Tokio

Tokio 是一个用于 Rust 编程语言的异步运行时,它提供了一种在单线程中管理多个并发任务的方式。它是基于 Rust 的异步编程模型构建的,这个模型利用了 Rust 的所有权(ownership)和生命周期(lifetimes)特性来保证内存安全。

Tokio 的核心是它的异步 I/O 模型,它允许程序在执行 I/O 操作(如网络请求或文件读写)时不需要阻塞线程。

如果你使用了Tokio,建议你还是使用tokio:io,而不是标准库std:io,这个看业务选择。

Tokio 还包括了一个事件循环(event loop),它负责调度和执行异步任务。这个事件循环可以处理成千上万的并发连接,所以Tokio非常适合用于构建高性能的网络应用,如 web 服务器、消息队列、实时通信系统等。

简单点说就是高性能中间件服务,例如Nginx这种服务基建。

同时,Tokio 还提供了许多实用的功能,如定时器、同步原语、TCP 和 UDP 网络协议等,以帮助开发者更轻松地构建复杂的网络应用。

三、基于Future实现

在Rust标准库中Future 是一个关键的概念,它是异步编程的基础。它代表了一个尚未完成的计算,可能在未来的某个时间点完成,并产生一个结果。

你可以完全类似的比作JavaScript中的Promise。

pub trait Future {type Output; // 关联类型,表示 Future 完成时产生的值类型fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>;
}

这里的 Poll 是一个枚举,它表示 poll 方法的可能结果:

pub enum Poll<T> {Ready(T),    // 异步操作已经完成,并返回一个值Pending,     // 异步操作尚未完成
}

这个 Future 对象可以被传递给执行上下文(如 Tokio 的运行时),执行上下文会定期调用 poll 方法来检查操作是否完成。如果操作完成,poll 方法会返回 Poll::Ready(result),其中 result 是操作的结果。如果操作尚未完成,poll 方法会返回 Poll::Pending,并且当操作有可能完成时,通知执行上下文重新调度 Future。

四、简单的示例

由于今天我们是初步认识Tokio,下面的例子都比较简单,但可以让你快速熟悉tokio的基本用法。

use tokio::time::Duration; // 注意这里使用的tokio提供的time,并非std#[tokio::main] //需要讲main函数设置为async并添加tokio::main注解async fn main() {println!("Hello before delay");tokio::time::sleep(Duration::from_secs(2)).await;println!("Hello after delay");}

五、TCP 客户端和服务端

// 服务端
use tokio::net::TcpListener;#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {let listener = TcpListener::bind("127.0.0.1:8080").await?;loop {let (mut socket, _) = listener.accept().await?;tokio::spawn(async move {let mut buf = [0; 1024];// 只要你使用tokio,那边这个io也是异步读取的!!!match socket.read(&mut buf).await {Ok(n) if n == 0 => return,Ok(n) => {println!("Received data: {}", String::from_utf8_lossy(&buf[..n]));}Err(e) => {eprintln!("Failed to read from socket; error = {}", e);}}});}
}// 客户端
use tokio::net::TcpStream;#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {let mut stream = TcpStream::connect("127.0.0.1:8080").await?;stream.write_all(b"hello world").await?;Ok(())
}

六、使用 select! 宏处理多个异步操作

这个特效有点像Golang的并非处理,只是Rust 的异步编程模型基于 async/await 语法和 futures,而 Go 使用了基于协程(goroutines)和通道(channels)的模型。

//golangselect {case msg1 := <-ch1:// 处理 msg1case msg2 := <-ch2:// 处理 msg2case <-time.After(time.Second):// 超时处理default:// 默认情况}
//rusttokio::select! {Some(msg1) = receiver.recv() => {// 处理 msg1}Some(msg2) = receiver2.recv() => {// 处理 msg2}_ = tokio::time::sleep(Duration::from_secs(1)) => {// 超时处理}}

今天分享就到这里,希望大家多多支持

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

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

相关文章

从“量子”到分子:探索计算的无限可能 | 综述荐读

在2023年年末&#xff0c;两篇划时代的研究报告在《科学》&#xff08;Science&#xff09;杂志上引发了广泛关注。这两篇论文分别来自两个研究小组&#xff0c;它们共同揭示了单氟化钙分子间相互作用的研究成果&#xff0c;成功地在这些分子间创造出了分子量子比特。这一成就不…

算法练习—day1

title: 算法练习—day1 date: 2024-04-03 21:49:55 tags: 算法 categories:LeetCode typora-root-url: 算法练习—day1 网址&#xff1a;https://red568.github.io 704. 二分查找 题目&#xff1a; 题目分析&#xff1a; 左右指针分别为[left,right]&#xff0c;每次都取中…

【机器学习】K-近邻算法(KNN)介绍、应用及文本分类实现

一、引言 1.1 K-近邻算法&#xff08;KNN&#xff09;的基本概念 K-近邻算法&#xff08;K-Nearest Neighbors&#xff0c;简称KNN&#xff09;是一种基于实例的学习算法&#xff0c;它利用训练数据集中与待分类样本最相似的K个样本的类别来判断待分类样本所属的类别。KNN算法…

ArcGIS Pro导出布局时去除在线地图水印

目录 一、背景 二、解决方法 一、背景 在ArcGIS Pro中经常会用到软件自带的在线地图&#xff0c;但是在导出布局时&#xff0c;图片右下方会自带地图的水印 二、解决方法 解决方法&#xff1a;添加动态文本--服务图层制作者名单&#xff0c;然后在布局中选定位置添加 在状…

FPGA_mipi

1 mipi接口 mipi(移动行业处理器接口&#xff0c;是为高速数据传输量身定做的&#xff0c;旨在解决日益增长的高清图像(视频)传输的高带宽要求与传统接口低速率之间的矛盾。 采用差分信号传输&#xff0c;在设计时需要按照差分设计的一般规则进行严格的设计。 mipi协议提出之际…

dhcp中继代理

不同过路由器分配ip了&#xff0c;通过一台服务器来代替&#xff0c;路由器充当中继代理功能&#xff0c;如下图 服务器地址&#xff1a;172.10.1.1/24 配置流程&#xff1a; 1.使能dhcp功能 2.各个接口网关地址&#xff0c;配置dhcp中继功能 dhcp select relay &#xff0…

Qt | 发布程序(以 minGW 编译器为例)

1、注意:修改 pro 文件后,最好执行“构建”>“重新构建项目”,否则 pro 文件的更改将不会反应到程序上。 2、发布程序的目的:就是让编译后生成的可执行文件(如 exe 文件),能在其他计算机上运行。 一、编译后生成的各种文件简介 Qt Creator 构建项目后产生的文件及目录…

实时渲染 -- 材质(Materials)

一、自然界中的材质 首先了解下自然界中的材质 如上这幅图&#xff0c;不同的物体、场景、组合&#xff0c;会让我们看到不同的效果。 我们通常认为物体由其表面定义&#xff0c;表面是物体和其他物体或周围介质之间的边界面。但是物体内部的材质也会影响光照效果。我们目前只…

C++ 程序自动重启(windows 有源码)

初级代码游戏的专栏介绍与文章目录-CSDN博客 程序长时间运行&#xff0c;内存泄漏&#xff0c;最后崩溃&#xff0c;怎么办&#xff1f; 程序24小时运行&#xff0c;偶发随机崩溃&#xff0c;怎么办&#xff1f; 啃代码、内存泄漏检查工具、分析线程交互……没人敢承诺解决问题…

续二叉搜索树递归玩法

文章目录 一、插入递归二、寻找递归&#xff08;非常简单&#xff0c;走流程就行&#xff09;三、插入递归&#xff08;理解起来比较麻烦&#xff09; 先赞后看&#xff0c;养成习惯&#xff01;&#xff01;&#xff01;^ _ ^<3 ❤️ ❤️ ❤️ 码字不易&#xff0c;大家的…

第六题:标题统计

题目描述 凯凯刚写了一篇美妙的作文&#xff0c;请问这篇作文的标题中有多少个字符&#xff1f; 注意&#xff1a;标题中可能包含大、小写英文字母、数字字符、空格和换行符。统计标题字符数时&#xff0c;空格和换行符不计算在内。 输入描述 输入文件只有一行&#xff0c;…

Java中IO、BIO、NIO、AIO分别是什么?

在Java中&#xff0c;IO、BIO、NIO、和AIO分别指不同的输入/输出处理模型。这些模型在处理数据流和网络通信时有各自的特点和使用场景。它们之间的区别&#xff1a; BIO (Blocking IO) - 同步阻塞IO 想象你在餐厅点餐。BIO就像是一对一的服务方式&#xff0c;即一个服务员为一…

ROS 2边学边练(11)-- colcon的使用

从此篇开始我们即将进入client library系列&#xff0c;主要包含包的创建、主题、服务、参数、消息等功能的自定义实现&#xff0c;开始真正进入ROS的大门咯。 前言 从ROS 1到ROS 2&#xff0c;对应的构建工具集由 catkin_make -> catkin_make_isolated ->catkin_tools …

Redis监控方案以及相关黄金指标提升稳定性和可靠性

Redis监控方案以及相关黄金指标提升稳定性和可靠性 1. 需要了解的词2. 「基准性能」相关指标2.1 Latency2.2 最大响应延迟2.3 平均响应延迟2.4 OPS(instantaneous_ops_per_sec)2.5 Hit Rate 3. 「内存」相关指标3.1 内存使用量(used_memory)3.2 内存碎片率(mem_fragmentation_r…

day18-二叉树part05

513.找树左下角的值 class Solution {public int findBottomLeftValue(TreeNode root) {int res 0;if(root null){return res;}Queue<TreeNode> que new LinkedList<>();que.add(root);while(!que.isEmpty()){int size que.size();for(int i 0;i < size;…

文件操作(详解)

该片博客有点长大家可以通过目录选择性阅读 这是个人主页 敲上瘾-CSDN博客 目录 1. 为什么使⽤⽂件&#xff1f; 2. 什么是⽂件&#xff1f; 2.1 程序⽂件 2.2 数据⽂件 2.3 ⽂件名 3. ⼆进制⽂件和⽂本⽂件&#xff1f; 4. ⽂件的打开和关闭 4.1 流和标准流 4.1.1 流…

【c/c++】深入探秘:C++内存管理的机制

&#x1f525;个人主页&#xff1a;Quitecoder &#x1f525;专栏&#xff1a;c笔记仓 朋友们大家好&#xff0c;本篇文章我们详细讲解c中的动态内存管理 目录 1.C/C内存分布2.C语言中动态内存管理方式&#xff1a;malloc/calloc/realloc/free3.c内存管理方式3.1new/delete对内…

【how2j练习题】JS部分阶段练习

练习题 1 <!-- 练习&#xff1a;自定义一个函数&#xff0c;对数组进行排序&#xff0c;要求排序后没有重复数据 --> <script>function p(s){document.write(s);document.write("<br>");}function uniquel(arr){ var hash[];for(var i 0;i<arr.…

Java源值1.5已过时,将在未来所有发行版中删除

1、背景 确认java项目没问题&#xff0c;但是启动的时候&#xff0c;却报错&#xff1a;java: -source 1.5 中不支持 diamond 运算符 2、解决 2.1 2.2 2.3 2.4 2.5

为什么索引的底层结构是B+树

B树 1.数据库与数据交互的单位是page,而B树的每个节点都是一个page,访问一个节点&#xff0c;就相当于进行了一次I/O操作。所以访问的节点越少&#xff0c;查找效率越大。而B树是矮胖的&#xff0c;查找深度也不会太大。 2.B树中的节点是有序存储的&#xff0c;对于范围查询、排…