Rust 并发编程:Futures、Tasks 和 Threads 的结合使用
一、线程(Threads)与异步(Async)的对比
1.1. 线程的优势与限制
线程是一种广泛使用的并发模型,几乎所有现代操作系统都支持。Rust 的标准库提供了 std::thread
API,使得线程编程变得直观。然而,线程也有一些限制:
- 每个线程占用较多内存(栈空间一般为 2MB 左右)。
- 线程的创建和销毁有一定的性能开销。
- 在没有操作系统支持的情况下(如某些嵌入式系统),线程模型无法使用。
1.2. 异步的优势与限制
异步编程基于 async
和 await
,提供了一种不同的并发方式,它的核心概念是 Future
。Rust 的 Future
由运行时管理,而非操作系统线程。其主要优势包括:
- 任务(Task)比线程更轻量级,适合大量并发操作。
- 适用于 IO 密集型任务,如处理多个网络请求、消息队列等。
- 任务之间可以高效地共享资源。
但异步编程也有一定的限制:
- 需要一个异步运行时(如
tokio
或async-std
)。 - 代码复杂度较高,尤其是涉及
Pin
、Send
和Sync
等特性的情况。 - 适用于 IO 绑定任务,而 CPU 密集型任务可能仍然需要线程。
二、线程与异步任务的结合使用
在许多实际场景中,我们可以同时使用线程和异步任务,以发挥各自的优势。例如,我们可以在后台线程中执行 CPU 密集型任务,并使用异步任务来管理 IO 任务。
2.1.线程和异步的对比示例
让我们来看一个例子:
use std::thread;
use std::time::Duration;
use async_channel::unbounded;
use tokio::task;#[tokio::main]
async fn main() {let (tx, rx) = unbounded();thread::spawn(move || {for i in 1..=10 {tx.send(i).unwrap();thread::sleep(Duration::from_secs(1));}});while let Ok(value) = rx.recv().await {println!("Received: {}", value);}
}
在这个例子中:
- 我们创建了一个
async_channel
以支持异步通信。 - 使用
thread::spawn
启动一个 OS 线程,在其中发送数据。 - 在主
async
任务中等待接收消息,并异步处理它们。
三、什么时候使用线程,什么时候使用异步?
在选择并发模型时,可以遵循以下原则:
- 线程适用于高并行计算(Parallelism):如 CPU 密集型任务,例如视频编码、图像处理、密码学计算等。
- 异步适用于高并发(Concurrency):如 IO 绑定任务,例如 Web 服务器、消息队列、数据库操作等。
- 结合使用:
- 如果某个任务主要是计算密集型,但仍然需要异步处理结果,使用
spawn_blocking
。 - 如果任务主要是异步的,但某些部分需要更高的并行度,可以在异步任务中启动线程。
- 如果某个任务主要是计算密集型,但仍然需要异步处理结果,使用
3.1. 结合线程和异步的应用场景
以下是几个实际应用示例:
- Web 服务器:在
async
代码中处理 HTTP 请求,但将 CPU 密集型任务交给线程池。 - 数据库访问:使用
async
处理数据库连接,但在后台线程执行复杂查询。 - 游戏引擎:使用
async
处理网络 IO,但使用多线程进行物理计算。
四、Rust 运行时的多线程支持
许多 Rust 异步运行时(如 tokio
)本身是多线程的。它们采用 工作窃取(Work Stealing) 机制,使任务能够在多个线程之间调度,从而提高 CPU 利用率。
use tokio::task;#[tokio::main]
async fn main() {let handle = task::spawn_blocking(|| {// 在专门的线程池中运行heavy_computation()});let result = handle.await.unwrap();println!("Computation result: {}", result);
}fn heavy_computation() -> i32 {// 执行 CPU 密集型任务42
}
在这里,我们使用 spawn_blocking
运行 CPU 密集型计算,同时保持异步任务的流畅性。
五、结论
Rust 提供了强大的并发工具,无论是基于线程的并发,还是基于 async
的异步,都有其适用的场景。两者并不互斥,而是可以结合使用,以充分利用计算资源。
- 如果任务是 CPU 密集型,使用线程。
- 如果任务是 IO 密集型,使用异步。
- 如果需要兼顾计算和 IO,则结合使用线程和异步。
Rust 的并发模型既安全又高效,为开发高性能应用提供了强大的支持。在接下来的 Rust 代码中,尝试灵活运用这些技巧吧!
相关文章:
Rust 并发编程:Futures、Tasks 和 Threads 的结合使用
一、线程(Threads)与异步(Async)的对比 1.1. 线程的优势与限制 线程是一种广泛使用的并发模型,几乎所有现代操作系统都支持。Rust 的标准库提供了 std::thread API,使得线程编程变得直观。然而࿰…...
常见的网络协议介绍
一、什么是网络协议 指的是通信双方的数据发送和接收顺序,数据的封装规则。 通俗解释:描述双方发送和接收的每个字节是按照什么规则。 二、TCP/IP体系的常用协议 (一)应用层 HTTP:超文本协议;指的是用来传输文本网页的协议&#…...
一文读懂加载地址、链接地址和运行地址
我们在做嵌入式系统开发时,会经常遇到加载地址、链接地址和运行地址的概念,可能会感到很困惑,搞不清它们三者的关系。希望此文能帮助大家彻底理解三者的关系。 一.概念 1.1.加载地址 加载地址,即Load Memory Address(…...
Unity帧同步与状态同步混合架构开发指南
一、技术背景与适用场景 1. 技术定位差异 帧同步(Lockstep):同步操作指令,强调确定性计算,适用于实时性要求高的场景(如MOBA、RTS),但存在反作弊难题16。 状态同步(Sta…...
后路式编程
今天遇到一个问题,反馈的时候,已经提审过了,不能重新出包了。只能依赖Lua热更解决。非常巧的是,C#那边的变量全是Public的,这算是救了一命。想想确实可笑,本来是封装的问题,没有封装的太好。结果…...
Rust语言入门与应用:未来发展趋势解析
一、Rust语言核心优势解析 1.1 内存安全革命 rust复制 // 所有权系统示例 fn main() { let s1 String::from("hello"); // s1获得所有权 let s2 s1; // 所有权转移至s2 // println!("{}", s1); // 编译错误!s1已失效 println!("{}&quo…...

【2025小白版】计算复试/保研机试模板(个人总结非GPT生成)附代码
一、编程语言选择 很多高校在机试中对编程语言都有明确规定,像复旦大学计算机学院就说明可选择 C、C 或 Java 语言答题,还支持 C11(gcc5.4),C14(g5.4),Java (openjdk1.8)…...

android11使用gpio口控制led状态灯
目录 一、简介 二、解决方法 A、底层驱动 B、上层调用 C、验证 一、简介 1、需求:这里是用2个gpio口来控制LED灯,开机时默认亮蓝灯,按开机键,休眠亮红灯,唤醒亮蓝灯。 原理图: 这里由于主板上电阻R63…...

基于Asp.net的高校一卡通管理系统
作者:计算机学姐 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等,“文末源码”。 专栏推荐:前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏:…...

C++蓝桥杯基础篇(七)
片头 嗨~小伙伴们,大家好!今天我们来一起学习蓝桥杯基础篇(七),学习相关字符串的知识,准备好了吗?咱们开始咯! 一、字符与整数的联系——ASCII码 每个常用字符都对应一个-128~127的…...

8.路由原理专题
路由器数据转发原理,路由表、FIB、快速转发表的关系 路由的控制平面与转发平面 控制平面:负责路由计算,维护;路由协议运行在控制平面 转发平面:进行数据包的封装,报文转发,路由表,FIB表,快速转发表等 控制平面与转发平面相互独立又协同工作 路由器检查数据包的目…...
jQuery UI 简介
jQuery UI 简介 引言 随着互联网技术的飞速发展,前端开发已经成为网站和应用程序建设的重要组成部分。jQuery UI 是一个基于 jQuery 的用户界面库,它为开发者提供了丰富的交互组件和视觉效果,使得创建具有吸引力和互动性的网页变得更加简单。本文将为您详细介绍 jQuery UI…...

Web服务器配置
配置虚拟主机 通过虚拟主机,可以实现用自定义的域名来访问,并且可以为不同的域名指定不同的站点目录。 配置IP地址和域名的映射关系 申请真实的域名需要一定的费用,为了方便开发,可以通过修改hosts文件来实现将任意域名解析到本…...

LINUX网络基础 [一] - 初识网络,理解网络协议
目录 前言 一. 计算机网络背景 1.1 发展历程 1.1.1 独立模式 1.1.2 网络互联 1.1.3 局域网LAN 1.1.4 广域网WAN 1.2 总结 二. "协议" 2.1 什么是协议 2.2 网络协议的理解 2.3 网络协议的分层结构 三. OSI七层模型(理论标准) …...
定制化开发的WooCommerce独立站商城更安全
定制化开发的WooCommerce独立站商城在安全性、交易风险控制以及整体用户体验方面有显著优势。以下是定制化开发在这些方面的具体表现: 1. 安全性更高 定制化开发允许开发者从底层架构开始设计和优化,确保网站的安全性。以下是具体表现: (1…...
Xcode 运行真机失败
错误提示: iPhone xxx is not available because it is unpaired. Pair with the device in the Xcode Devices Window, and respond to any pairing prompts on the device. 处理方法: 把Xcode关闭,手机断开数据线,打开终端&…...

【FFmpeg之如何新增一个硬件解码器】
FFmpeg之如何新增一个硬件解码器 前言一、config配置二、解码器定义1.目录结构2.数据结构 三、解码流程1、初始化mediacodec_decode_init2、帧接收mediacodec_receive_frame2.1 解码上下文MediaCodecH264DecContext2.2 发包AVPacket到解码器 -- ff_mediacodec_dec_send2.3 接收…...

P3385 【模板】负环
P3385 【模板】负环 - 洛谷 题目描述 给定一个 n 个点的有向图,请求出图中是否存在从顶点 1 出发能到达的负环。 负环的定义是:一条边权之和为负数的回路。 输入格式 本题单测试点有多组测试数据。 输入的第一行是一个整数 T,表示测试数…...

破解透明物体抓取难题,地瓜机器人CASIA 推出几何和语义融合的单目抓取方案|ICRA 2025
概述 近日,全球机器人领域顶会ICRA 2025(IEEE机器人与自动化国际会议)公布论文录用结果,地瓜机器人主导研发的DOSOD开放词汇目标检测算法与MODEST单目透明物体抓取算法成功入选。前者通过动态语义理解框架提升复杂场景识别准确率…...

深度学习编译器(整理某survey)
一、深度学习框架 TensorFlow PyTorch MXNet ONNX:定义了一个统一的表示,DL models的格式方便不同框架之间的转换模型 二、深度学习硬件 通用硬件(CPU、GPU):通过硬件和软件优化支持深度学习工作负载 GPU:通过多核架构实现高…...

wordpress后台更新后 前端没变化的解决方法
使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…...
Admin.Net中的消息通信SignalR解释
定义集线器接口 IOnlineUserHub public interface IOnlineUserHub {/// 在线用户列表Task OnlineUserList(OnlineUserList context);/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...
IGP(Interior Gateway Protocol,内部网关协议)
IGP(Interior Gateway Protocol,内部网关协议) 是一种用于在一个自治系统(AS)内部传递路由信息的路由协议,主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...
uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖
在前面的练习中,每个页面需要使用ref,onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入,需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...

CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

YSYX学习记录(八)
C语言,练习0: 先创建一个文件夹,我用的是物理机: 安装build-essential 练习1: 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件,随机修改或删除一部分,之后…...

【项目实战】通过多模态+LangGraph实现PPT生成助手
PPT自动生成系统 基于LangGraph的PPT自动生成系统,可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析:自动解析Markdown文档结构PPT模板分析:分析PPT模板的布局和风格智能布局决策:匹配内容与合适的PPT布局自动…...
【Go】3、Go语言进阶与依赖管理
前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课,做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程,它的核心机制是 Goroutine 协程、Channel 通道,并基于CSP(Communicating Sequential Processes࿰…...

Android15默认授权浮窗权限
我们经常有那种需求,客户需要定制的apk集成在ROM中,并且默认授予其【显示在其他应用的上层】权限,也就是我们常说的浮窗权限,那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...
Swagger和OpenApi的前世今生
Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章,二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑: 🔄 一、起源与初创期:Swagger的诞生(2010-2014) 核心…...