Rust中的并发与多线程:高级技术

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

Rust中的并发与多线程:高级水平

\n\n

并发与多线程是系统编程中最强大同时也最复杂的方面之一。Rust提供了一种独特的方法:在编译阶段保证内存安全,消除数据竞争和悬垂指针。在本文中,我们将深入探讨Rust中并发的高级技术,包括async/await、Tokio库、Send和Sync trait,以及底层同步原语。

\n\n

本文面向已经熟悉Rust基础知识并希望深入研究高性能并行计算的开发者。

\n\n

1. 并发模型:操作系统线程与异步

\n\n

Rust支持两种主要模型:操作系统线程和异步任务。两者之间的选择取决于具体场景:对于CPU密集型任务,线程更合适;对于I/O密集型任务,则适合使用async。

\n\n

操作系统线程 (std::thread)

\n\n

在Rust中创建线程很简单,但需要注意数据所有权:

\n\n
use std::thread;\n\nlet data = vec![1, 2, 3];\n\nlet handle = thread::spawn(move || {\n    println!("{:?}", data);\n});\n\nhandle.join().unwrap();
\n\n

关键点是move关键字。它将所有权转移给闭包。如果需要在线程之间共享数据,请使用Arc<Mutex<T>>。

\n\n

异步编程 (async/await)

\n\n

异步代码在单个线程内运行,在等待I/O时在任务之间切换。这降低了上下文切换的开销。一个简单的异步函数示例:

\n\n
use tokio::time::{sleep, Duration};\n\n#[tokio::main]\nasync fn main() {\n    let task1 = async_task("任务 1");\n    let task2 = async_task("任务 2");\n\n    tokio::join!(task1, task2);\n}\n\nasync fn async_task(name: &str) {\n    println!("{} 开始", name);\n    sleep(Duration::from_secs(1)).await;\n    println!("{} 完成", name);\n}
\n\n

tokio库是异步Rust的标准。它提供了一个多线程工作窃取调度器,可以有效地将任务分配到CPU核心上。

\n\n

2. Send和Sync trait:并发安全

\n\n

两个关键的trait确保了Rust中的并发安全:

\n\n
    \n
  • Send — 类型可以安全地在线程之间传递。
  • \n
  • Sync — 类型可以安全地从多个线程同时引用。
  • \n
\n\n

大多数Rust原语会自动实现这些trait,前提是它们的组件也实现了它们。例如,Arc<Mutex<i32>>实现了Send和Sync,而Rc<RefCell<i32>>则没有。

\n\n

考虑一个由于违反Send而无法编译的示例:

\n\n
use std::rc::Rc;\nuse std::thread;\n\nlet data = Rc::new(5);\n\nthread::spawn(move || {\n    println!("{}", data);\n}); // 错误:Rc<i32> 未实现 Send
\n\n

Rust编译器会给出清晰的错误信息,在编译阶段防止数据竞争。这是该语言的主要优势之一。

\n\n

3. 高级同步:通道、互斥锁和RwLock

\n\n

为了在线程之间交换数据,Rust提供了几个原语。让我们看看最强大的几个。

\n\n

通道 (mpsc)

\n\n

多生产者、单消费者通道允许从多个线程向一个接收器发送消息:

\n\n
use std::sync::mpsc;\nuse std::thread;\n\nlet (tx, rx) = mpsc::channel();\n\nfor i in 0..3 {\n    let tx_clone = tx.clone();\n    thread::spawn(move || {\n        tx_clone.send(i).unwrap();\n    });\n}\n\ndrop(tx); // 关闭发送端\n\nfor received in rx {\n    println!("收到: {}", received);\n}
\n\n

通道非常适合“生产者-

博客

书籍推荐