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

Rust 并发编程:Futures、Tasks 和 Threads 的结合使用

一、线程(Threads)与异步(Async)的对比

1.1. 线程的优势与限制

线程是一种广泛使用的并发模型,几乎所有现代操作系统都支持。Rust 的标准库提供了 std::thread API,使得线程编程变得直观。然而,线程也有一些限制:

  • 每个线程占用较多内存(栈空间一般为 2MB 左右)。
  • 线程的创建和销毁有一定的性能开销。
  • 在没有操作系统支持的情况下(如某些嵌入式系统),线程模型无法使用。

1.2. 异步的优势与限制

异步编程基于 asyncawait,提供了一种不同的并发方式,它的核心概念是 Future。Rust 的 Future 由运行时管理,而非操作系统线程。其主要优势包括:

  • 任务(Task)比线程更轻量级,适合大量并发操作。
  • 适用于 IO 密集型任务,如处理多个网络请求、消息队列等。
  • 任务之间可以高效地共享资源。

但异步编程也有一定的限制:

  • 需要一个异步运行时(如 tokioasync-std)。
  • 代码复杂度较高,尤其是涉及 PinSendSync 等特性的情况。
  • 适用于 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,使得线程编程变得直观。然而&#xff0…...

常见的网络协议介绍

一、什么是网络协议 指的是通信双方的数据发送和接收顺序,数据的封装规则。 通俗解释:描述双方发送和接收的每个字节是按照什么规则。 二、TCP/IP体系的常用协议 (一)应用层 HTTP:超文本协议;指的是用来传输文本网页的协议&#…...

一文读懂加载地址、链接地址和运行地址

我们在做嵌入式系统开发时,会经常遇到加载地址、链接地址和运行地址的概念,可能会感到很困惑,搞不清它们三者的关系。希望此文能帮助大家彻底理解三者的关系。 一.概念 1.1.加载地址 加载地址,即Load Memory Address&#xff08…...

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&#xff09…...

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语言&#xff0c;练习0&#xff1a; 先创建一个文件夹&#xff0c;我用的是物理机&#xff1a; 安装build-essential 练习1&#xff1a; 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件&#xff0c;随机修改或删除一部分&#xff0c;之后…...

【项目实战】通过多模态+LangGraph实现PPT生成助手

PPT自动生成系统 基于LangGraph的PPT自动生成系统&#xff0c;可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析&#xff1a;自动解析Markdown文档结构PPT模板分析&#xff1a;分析PPT模板的布局和风格智能布局决策&#xff1a;匹配内容与合适的PPT布局自动…...

【Go】3、Go语言进阶与依赖管理

前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课&#xff0c;做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程&#xff0c;它的核心机制是 Goroutine 协程、Channel 通道&#xff0c;并基于CSP&#xff08;Communicating Sequential Processes&#xff0…...

Android15默认授权浮窗权限

我们经常有那种需求&#xff0c;客户需要定制的apk集成在ROM中&#xff0c;并且默认授予其【显示在其他应用的上层】权限&#xff0c;也就是我们常说的浮窗权限&#xff0c;那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...

Swagger和OpenApi的前世今生

Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章&#xff0c;二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑&#xff1a; &#x1f504; 一、起源与初创期&#xff1a;Swagger的诞生&#xff08;2010-2014&#xff09; 核心…...