Skip to content

Rust 并发编程

并发编程是现代编程中的重要部分,Rust 提供了强大的并发编程支持。本章节将介绍 Rust 中的并发编程模型。

线程

Rust 使用 std::thread 模块来创建和管理线程:

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

fn main() {
    // 创建一个新线程
    let handle = thread::spawn(|| {
        for i in 1..10 {
            println!("Thread: {}", i);
            thread::sleep(Duration::from_millis(100));
        }
    });
    
    // 主线程继续执行
    for i in 1..5 {
        println!("Main: {}", i);
        thread::sleep(Duration::from_millis(150));
    }
    
    // 等待子线程完成
    handle.join().unwrap();
}

共享状态

互斥锁

使用 Mutex<T> 来实现线程间的共享状态:

rust
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<T> 来实现读写分离:

rust
use std::sync::{Arc, RwLock};
use std::thread;

fn main() {
    let data = Arc::new(RwLock::new(0));
    
    // 读线程
    for i in 0..5 {
        let data = Arc::clone(&data);
        thread::spawn(move || {
            let value = data.read().unwrap();
            println!("Reader {}: {}", i, *value);
        });
    }
    
    // 写线程
    for i in 0..3 {
        let data = Arc::clone(&data);
        thread::spawn(move || {
            let mut value = data.write().unwrap();
            *value = i;
            println!("Writer {}: {}", i, *value);
        });
    }
    
    // 等待所有线程完成
    thread::sleep(std::time::Duration::from_secs(1));
}

消息传递

使用通道(channel)来实现线程间的通信:

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

fn main() {
    // 创建通道
    let (tx, rx) = mpsc::channel();
    
    // 发送线程
    thread::spawn(move || {
        let messages = ["Hello", "from", "the", "thread"];
        for msg in messages {
            tx.send(msg).unwrap();
        }
    });
    
    // 接收线程(主线程)
    for received in rx {
        println!("Received: {}", received);
    }
}

多发送者

使用 mpsc::Sender 来实现多发送者:

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

fn main() {
    let (tx, rx) = mpsc::channel();
    
    // 创建多个发送者
    let tx1 = tx.clone();
    let tx2 = tx.clone();
    
    thread::spawn(move || {
        tx1.send("Hello from thread 1").unwrap();
    });
    
    thread::spawn(move || {
        tx2.send("Hello from thread 2").unwrap();
    });
    
    thread::spawn(move || {
        tx.send("Hello from thread 3").unwrap();
    });
    
    // 接收所有消息
    for received in rx {
        println!("Received: {}", received);
    }
}

同步原语

条件变量

使用 Condvar 来实现条件等待:

rust
use std::sync::{Arc, Mutex, Condvar};
use std::thread;

fn main() {
    let pair = Arc::new((Mutex::new(false), Condvar::new()));
    let pair2 = Arc::clone(&pair);
    
    thread::spawn(move || {
        let (lock, cvar) = &*pair2;
        let mut started = lock.lock().unwrap();
        *started = true;
        cvar.notify_one();
    });
    
    let (lock, cvar) = &*pair;
    let mut started = lock.lock().unwrap();
    while !*started {
        started = cvar.wait(started).unwrap();
    }
    
    println!("Thread started");
}

信号量

使用 Semaphore 来限制并发访问:

rust
use std::sync::Arc;
use std::sync::Semaphore;
use std::thread;

fn main() {
    let semaphore = Arc::new(Semaphore::new(3)); // 最多允许3个线程同时访问
    
    let mut handles = vec![];
    for i in 0..10 {
        let semaphore = Arc::clone(&semaphore);
        let handle = thread::spawn(move || {
            let _permit = semaphore.acquire().unwrap();
            println!("Thread {} is working", i);
            thread::sleep(std::time::Duration::from_secs(1));
            println!("Thread {} is done", i);
        });
        handles.push(handle);
    }
    
    for handle in handles {
        handle.join().unwrap();
    }
}

原子操作

使用原子类型来实现无锁并发:

rust
use std::sync::Arc;
use std::sync::atomic::{AtomicUsize, Ordering};
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));
}

总结

  • 线程:使用 std::thread 创建和管理线程
  • 共享状态:使用 Mutex<T>RwLock<T> 实现线程间共享状态
  • 消息传递:使用通道(channel)实现线程间通信
  • 同步原语:使用 CondvarSemaphore 等同步原语
  • 原子操作:使用原子类型实现无锁并发

Rust 的并发编程模型既安全又高效,通过所有权和借用规则,Rust 可以在编译时防止数据竞争等并发问题。通过本章节的学习,你应该已经掌握了 Rust 中的并发编程方法。