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

Rust并发编程:线程、通道与锁深度解析

Rust并发编程:线程、通道与锁深度解析

引言

在Rust开发中,并发编程是构建高性能应用的关键。作为一名从Python转向Rust的后端开发者,我深刻体会到Rust在并发安全方面的优势。Rust通过所有权系统和类型安全,在编译时保证并发安全,无需运行时同步开销。

并发编程核心概念

并发vs并行

概念含义
并发多个任务交替执行,同一时刻只有一个任务在执行
并行多个任务同时执行,需要多核CPU支持

Rust并发原语

  • 线程std::thread
  • 通道std::sync::mpsccrossbeam-channel
  • std::sync::Mutex,std::sync::RwLock
  • 原子操作std::sync::atomic
  • 条件变量std::sync::Condvar

环境搭建与基础配置

基本线程创建

use std::thread; use std::time::Duration; fn main() { let handle = thread::spawn(|| { for i in 1..10 { println!("Spawned thread: {}", i); thread::sleep(Duration::from_millis(1)); } }); for i in 1..5 { println!("Main thread: {}", i); thread::sleep(Duration::from_millis(1)); } handle.join().unwrap(); }

线程返回值

use std::thread; fn main() { let handle = thread::spawn(|| { "Hello from thread" }); let result = handle.join().unwrap(); println!("{}", result); }

通道通信实战

单生产者单消费者

use std::sync::mpsc; use std::thread; 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!("Received: {}", received); }

多生产者

use std::sync::mpsc; use std::thread; fn main() { let (tx, rx) = mpsc::channel(); let tx1 = tx.clone(); thread::spawn(move || { tx.send(String::from("from thread 1")).unwrap(); }); thread::spawn(move || { tx1.send(String::from("from thread 2")).unwrap(); }); for received in rx { println!("Received: {}", received); } }

使用crossbeam-channel

use crossbeam_channel as channel; use std::thread; fn main() { let (s, r) = channel::unbounded(); thread::spawn(move || { s.send(42).unwrap(); }); println!("Received: {}", r.recv().unwrap()); }

锁机制实战

Mutex锁

use std::sync::{Arc, Mutex}; use std::thread; fn main() { let counter = Arc::new(Mutex::new(0)); let mut handles = vec![]; for _ in 0..10 { let counter = Arc::clone(&counter); let handle = thread::spawn(move || { let mut num = counter.lock().unwrap(); *num += 1; }); handles.push(handle); } for handle in handles { handle.join().unwrap(); } println!("Result: {}", *counter.lock().unwrap()); }

RwLock读写锁

use std::sync::{Arc, RwLock}; use std::thread; fn main() { let data = Arc::new(RwLock::new(vec![1, 2, 3])); let readers: Vec<_> = (0..3) .map(|i| { let data = Arc::clone(&data); thread::spawn(move || { let d = data.read().unwrap(); println!("Reader {}: {:?}", i, *d); }) }) .collect(); let writer = thread::spawn(move || { let mut d = data.write().unwrap(); d.push(4); println!("Writer: {:?}", *d); }); for reader in readers { reader.join().unwrap(); } writer.join().unwrap(); }

原子操作实战

use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::Arc; use std::thread; fn main() { let counter = Arc::new(AtomicUsize::new(0)); let mut handles = vec![]; for _ in 0..10 { let counter = Arc::clone(&counter); let handle = thread::spawn(move || { for _ in 0..1000 { counter.fetch_add(1, Ordering::SeqCst); } }); handles.push(handle); } for handle in handles { handle.join().unwrap(); } println!("Result: {}", counter.load(Ordering::SeqCst)); }

实际业务场景

场景一:并行数据处理

use std::thread; fn process_chunk(chunk: Vec<i32>) -> Vec<i32> { chunk.into_iter().map(|x| x * 2).collect() } fn main() { let data = vec![1, 2, 3, 4, 5, 6, 7, 8]; let chunk_size = data.len() / 4; let mut handles = vec![]; for i in 0..4 { let start = i * chunk_size; let end = if i == 3 { data.len() } else { (i + 1) * chunk_size }; let chunk = data[start..end].to_vec(); let handle = thread::spawn(move || process_chunk(chunk)); handles.push(handle); } let mut results = vec![]; for handle in handles { let result = handle.join().unwrap(); results.extend(result); } println!("Results: {:?}", results); }

场景二:工作池模式

use std::sync::mpsc; use std::thread; struct Worker { id: usize, thread: Option<thread::JoinHandle<()>>, } impl Worker { fn new(id: usize, receiver: mpsc::Receiver<Job>) -> Self { let thread = thread::spawn(move || loop { let job = receiver.recv(); match job { Ok(job) => { println!("Worker {} executing job", id); job(); } Err(_) => { println!("Worker {} disconnected", id); break; } } }); Worker { id, thread: Some(thread), } } } type Job = Box<dyn FnOnce() + Send + 'static>; struct ThreadPool { workers: Vec<Worker>, sender: mpsc::Sender<Job>, } impl ThreadPool { fn new(size: usize) -> Self { let (sender, receiver) = mpsc::channel(); let receiver = std::sync::Arc::new(std::sync::Mutex::new(receiver)); let mut workers = Vec::with_capacity(size); for id in 0..size { workers.push(Worker::new(id, std::sync::Arc::clone(&receiver))); } ThreadPool { workers, sender } } fn execute<F>(&self, f: F) where F: FnOnce() + Send + 'static, { self.sender.send(Box::new(f)).unwrap(); } } fn main() { let pool = ThreadPool::new(4); for i in 0..8 { pool.execute(move || { println!("Processing task {}", i); }); } }

性能优化

使用scoped threads

use std::thread; fn main() { let mut arr = vec![1, 2, 3, 4]; thread::scope(|s| { for i in 0..arr.len() { s.spawn(move || { arr[i] *= 2; }); } }); println!("{:?}", arr); }

使用rayon进行并行迭代

use rayon::prelude::*; fn main() { let mut arr = vec![1, 2, 3, 4, 5]; arr.par_iter_mut().for_each(|x| *x *= 2); println!("{:?}", arr); }

总结

Rust的并发编程能力非常强大,通过所有权系统在编译时保证并发安全。从Python开发者的角度来看,Rust的并发模型更加严谨和安全,但学习曲线较陡。

在实际项目中,建议根据业务场景选择合适的并发原语,并注意性能优化和代码可读性。

http://www.jsqmd.com/news/848992/

相关文章:

  • 别再让电机‘刹不住车’:用ADRC的TD模块实现位置精准无超调控制(附STM32代码)
  • RIS辅助的模拟Air-ODE网络技术解析与应用
  • 蓝桥杯EDA国赛备赛避坑:从省赛PCB翻车案例,聊聊封装绑定与布局走线的那些细节
  • ARM Cortex-M软件浮点编译配置与实践
  • 国产高性能MCU如何破局?拆解先楫半导体RISC-V芯片的落地逻辑
  • Java程序员转行大模型开发:后端开发轻松转型大模型应用开发,
  • 告别轮询!用STM32F407的串口空闲中断+DMA,让你的串口通信效率翻倍(标准库实战)
  • ChromaControl终极指南:如何用一款软件统一控制所有RGB设备灯光效果
  • 拓璞数控明日上市:募资17亿港元 暗盘大涨51% 公司市值163亿港元
  • AI 智慧化健康管理系统:用前沿技术重构全民健康管理模式
  • 从傅里叶到拉普拉斯:给信号处理新手的直观对比指南(附性质对照表)
  • 科研截止日前夜崩溃预警:Perplexity文献管理5大隐形陷阱,92%用户已中招却浑然不觉
  • VideoDownloadHelper架构解析:浏览器原生视频解析引擎实现原理
  • Rust异步运行时:Tokio深度解析与实战
  • Perplexity健康科普查询深度拆解(临床医生都在用的7个隐藏技巧)
  • 避开这些坑!西门子PLC中AT参数覆盖功能的8个关键限制与实战避坑指南
  • 深入解析Arm Cortex-A53 Cache架构:从原理到多核一致性与性能优化实践
  • 金晟新能源冲刺港股:年营收22亿,亏1.7亿 李森家族色彩浓厚
  • 保姆级教程:手把手教你设置松下DP102负压传感器,解决空压机不停机过热问题
  • 从CP2102到CH9102:一次国产芯片替换的实战记录(附免按键下载避坑指南)
  • 保姆级教程:在ROS Noetic下为UR5机械臂配置RobotIQ FT300力传感器(含Gazebo仿真避坑指南)
  • ARM GCS机制解析:硬件级栈保护与性能优化
  • 从内容传播看《幸福的囚徒》的反差记忆点
  • STM32F4/F7上跑AI手写识别:从CUBEMX配置到串口通信的完整避坑指南
  • 从LMS到BLMS:自适应滤波的‘批处理’思想如何解决工程中的收敛难题?
  • 训练和微调
  • 如何在3分钟内将缠论分析从复杂理论变为可视化交易利器?
  • AI写论文指南!4款超实用AI论文生成工具,解决论文写作难题!
  • 建模也有Skills了:MWORKS.Sysplorer Skills已开源至MoHub!
  • Perplexity薪资查询失效了?4步紧急修复方案,含Chrome DevTools实时抓包教程