Rust并发编程:线程、通道与锁深度解析
Rust并发编程线程、通道与锁深度解析引言在Rust开发中并发编程是构建高性能应用的关键。作为一名从Python转向Rust的后端开发者我深刻体会到Rust在并发安全方面的优势。Rust通过所有权系统和类型安全在编译时保证并发安全无需运行时同步开销。并发编程核心概念并发vs并行概念含义并发多个任务交替执行同一时刻只有一个任务在执行并行多个任务同时执行需要多核CPU支持Rust并发原语线程std::thread通道std::sync::mpsc或crossbeam-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-channeluse 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: Veci32) - Veci32 { 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: Optionthread::JoinHandle(), } impl Worker { fn new(id: usize, receiver: mpsc::ReceiverJob) - 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 Boxdyn FnOnce() Send static; struct ThreadPool { workers: VecWorker, sender: mpsc::SenderJob, } 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 executeF(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 threadsuse 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的并发模型更加严谨和安全但学习曲线较陡。在实际项目中建议根据业务场景选择合适的并发原语并注意性能优化和代码可读性。