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

HoRain云--Rust 并发编程

🎬 HoRain 云小助手:个人主页

⛺️生活的理想,就是为了理想的生活!


⛳️ 推荐

前些天发现了一个超棒的服务器购买网站,性价比超高,大内存超划算!忍不住分享一下给大家。点击跳转到网站。

目录

⛳️ 推荐

线程

实例

实例

实例

实例

join 方法

实例

move 强制所有权迁移

实例

实例

消息传递

实例


安全高效的处理并发是 Rust 诞生的目的之一,主要解决的是服务器高负载承受能力。

并发(concurrent)的概念是指程序不同的部分独立执行,这与并行(parallel)的概念容易混淆,并行强调的是"同时执行"。

并发往往会造成并行。

本章讲述与并发相关的编程概念和细节。

线程

线程(thread)是一个程序中独立运行的一个部分。

线程不同于进程(process)的地方是线程是程序以内的概念,程序往往是在一个进程中执行的。

在有操作系统的环境中进程往往被交替地调度得以执行,线程则在进程以内由程序进行调度。

由于线程并发很有可能出现并行的情况,所以在并行中可能遇到的死锁、延宕错误常出现于含有并发机制的程序。

为了解决这些问题,很多其它语言(如 Java、C#)采用特殊的运行时(runtime)软件来协调资源,但这样无疑极大地降低了程序的执行效率。

C/C++ 语言在操作系统的最底层也支持多线程,且语言本身以及其编译器不具备侦察和避免并行错误的能力,这对于开发者来说压力很大,开发者需要花费大量的精力避免发生错误。

Rust 不依靠运行时环境,这一点像 C/C++ 一样。

但 Rust 在语言本身就设计了包括所有权机制在内的手段来尽可能地把最常见的错误消灭在编译阶段,这一点其他语言不具备。

但这不意味着我们编程的时候可以不小心,迄今为止由于并发造成的问题还没有在公共范围内得到完全解决,仍有可能出现错误,并发编程时要尽量小心!

Rust 中通过 std::thread::spawn 函数创建新线程:

实例

use std::thread;
use std::time::Duration;

fn spawn_function() {
for i in 0..5 {
println!("spawned thread print {}", i);
thread::sleep(Duration::from_millis(1));
}
}

fn main() {
thread::spawn(spawn_function);

for i in 0..3 {
println!("main thread print {}", i);
thread::sleep(Duration::from_millis(1));
}
}

运行结果:

main thread print 0 spawned thread print 0 main thread print 1 spawned thread print 1 main thread print 2 spawned thread print 2

这个结果在某些情况下顺序有可能变化,但总体上是这样打印出来的。

此程序有一个子线程,目的是打印 5 行文字,主线程打印三行文字,但很显然随着主线程的结束,spawn 线程也随之结束了,并没有完成所有打印。

std::thread::spawn 函数的参数是一个无参函数,但上述写法不是推荐的写法,我们可以使用闭包(closures)来传递函数作为参数:

实例

use std::thread;
use std::time::Duration;

fn main() {
thread::spawn(|| {
for i in 0..5 {
println!("spawned thread print {}", i);
thread::sleep(Duration::from_millis(1));
}
});

for i in 0..3 {
println!("main thread print {}", i);
thread::sleep(Duration::from_millis(1));
}
}

闭包是可以保存进变量或作为参数传递给其他函数的匿名函数。闭包相当于 Rust 中的 Lambda 表达式,格式如下:

|参数1, 参数2, ...| -> 返回值类型 { // 函数体 }

例如:

实例

fn main() {
let inc = |num: i32| -> i32 {
num + 1
};
println!("inc(5) = {}", inc(5));
}

运行结果:

inc(5) = 6

闭包可以省略类型声明使用 Rust 自动类型判断机制:

实例

fn main() {
let inc = |num| {
num + 1
};
println!("inc(5) = {}", inc(5));
}

结果没有变化。

join 方法

实例

use std::thread;
use std::time::Duration;

fn main() {
let handle = thread::spawn(|| {
for i in 0..5 {
println!("spawned thread print {}", i);
thread::sleep(Duration::from_millis(1));
}
});

for i in 0..3 {
println!("main thread print {}", i);
thread::sleep(Duration::from_millis(1));
}

handle.join().unwrap();
}

运行结果:

main thread print 0 spawned thread print 0 spawned thread print 1 main thread print 1 spawned thread print 2 main thread print 2 spawned thread print 3 spawned thread print 4

join 方法可以使子线程运行结束后再停止运行程序。

move 强制所有权迁移

这是一个经常遇到的情况:

实例

use std::thread;

fn main() {
let s = "hello";

let handle = thread::spawn(|| {
println!("{}", s);
});

handle.join().unwrap();
}

在子线程中尝试使用当前函数的资源,这一定是错误的!因为所有权机制禁止这种危险情况的产生,它将破坏所有权机制销毁资源的一定性。我们可以使用闭包的 move 关键字来处理:

实例

use std::thread;

fn main() {
let s = "hello";

let handle = thread::spawn(move || {
println!("{}", s);
});

handle.join().unwrap();
}

消息传递

Rust 中一个实现消息传递并发的主要工具是通道(channel),通道有两部分组成,一个发送者(transmitter)和一个接收者(receiver)。

std::sync::mpsc 包含了消息传递的方法:

实例

use std::thread;
use std::sync::mpsc;

fn main() {
let (tx, rx) = mpsc::channel();

thread::spawn(move || {
let val = String::from("hi");
tx.send(val).unwrap();
});

let received = rx.recv().unwrap();
println!("Got: {}", received);
}

运行结果:

Got: hi

子线程获得了主线程的发送者 tx,并调用了它的 send 方法发送了一个字符串,然后主线程就通过对应的接收者 rx 接收到了。

❤️❤️❤️本人水平有限,如有纰漏,欢迎各位大佬评论批评指正!😄😄😄

💘💘💘如果觉得这篇文对你有帮助的话,也请给个点赞、收藏下吧,非常感谢!👍 👍 👍

🔥🔥🔥Stay Hungry Stay Foolish 道阻且长,行则将至,让我们一起加油吧!🌙🌙🌙

http://www.zskr.cn/news/1510233.html

相关文章:

  • 【毕业设计】基于 SpringBoot 的家教供需匹配与在线预约系统设计基于SpringBoot的家教信息匹配与预约系统(源码+文档+远程调试,全bao定制等)
  • 如何构建高并发网盘直链解析服务:基于Vert.x的架构设计与实现
  • 甘肃省黄金白银回收铂金旧金回收无套路门店 TOP 榜单 实地测评资料整理(更新时间:2026-06-12_11:10:26) - 诚金汇钻回收公司
  • 免费将PS5/PS4手柄完美适配PC游戏:DS4Windows终极使用指南
  • 2026 高位黄金变现 南京正规回收门店排名,首选合扬 - 开心测评
  • 2026常州本地黄金铂金白银金条回收哪家靠谱?TOP5 正规实体门店榜单 + 电话地址(更新时间:2026-06-12_11:10:26) - 中安检金银铂钻回收
  • 串口数据秒变动态波形图:PyQt5界面+pyqtgraph实时绘图工具
  • 2026 盘锦卫生间漏水不用砸砖?微创补漏靠谱方案 - 苏易修缮
  • 项目紧急迭代、无接口文档时如何开展接口测试
  • 河南淇滨区黄金回收实测:2026年新规下如何安全变现?这3家30年零差评老店给出答案 - 行行星
  • 原神帧率解锁工具深度解析:突破60帧限制的完整技术指南
  • SPM8 MRI图像处理稳定工具包:体素运算、非线性配准与B样条插值全支持
  • 2026湖北出手黄金铂金白银回收避坑指南 5 家经营多年实体回收门店走访测评 + 详细地址(更新时间:2026-06-12_11:10:26) - 中业金奢再生回收中心
  • 告别拥挤桌面:用开源虚拟显示器免费扩展Windows屏幕空间
  • 2026 辽阳卫生间漏水不用砸砖?微创补漏靠谱方案 - 苏易修缮
  • 别再乱接地了!从PCB设计实战聊聊单点、多点、混合接地的选择(附高频/低频场景判断)
  • 2026企业架构实战:原料备货智能提醒与供应链多系统串联的非侵入式破局之路
  • ThinkPad风扇控制终极指南:如何用TPFanCtrl2实现完美散热与静音平衡
  • GPT-4稀疏激活真相:万亿参数模型如何靠2%激活率落地生产
  • 别再死记硬背时序图了!用STM32的GPIO开漏模式,手把手带你理解IIC总线的‘线与’奥秘
  • 音乐界的 TVBox?全平台兼容的开源播放器,聚合音乐平台!听遍全网音乐!
  • 泰坦尼克号生存预测实战包:带标注训练集、测试样本、预处理数据和两版可运行Python代码
  • 2026博尔塔拉黄金回收铂金回收银饰回收优质商户排名 TOP 线下实体门店实地走访资料汇总(更新时间:2026-06-12_11:10:26) - 信誉隆金银铂奢回收
  • 2026年6月折弯自动化十大品牌盘点:百超缘何稳居第一梯队 - 品牌推荐大师1
  • 汽车ECU诊断入门:手把手教你理解和使用UDS的10服务(诊断会话控制)
  • Memos Docker部署实战指南:从零到企业级的最佳实践深度解析
  • 2026厦门劳力士回收避雷指南!本地人专属高价出手套路拆解 - 开心测评
  • 告别硬编码:从Splish CrackMe出发,聊聊软件保护中那些‘一眼假’的验证逻辑
  • 2026 年全国优质打圈机生产企业排行榜 - 深度智识库
  • 2026 年 6 月最新 | 上海云仓公司哪家好 电商 / 跨境优选云仓,一站式代发退货处理,口碑服务商 - 商业新知