- 使用
Mutex
来保证线程安全:
- 在Rust中,
Mutex
(互斥锁)是一种同步原语,用于保护共享资源,确保同一时间只有一个线程可以访问该资源。
- 结合Rust的所有权和借用机制,可以有效避免数据竞争。
- 代码示例:
use std::sync::{Arc, Mutex};
use std::thread;
fn main() {
let shared_data = Arc::new(Mutex::new(0));
let mut handles = vec![];
for _ in 0..10 {
let data = Arc::clone(&shared_data);
let handle = thread::spawn(move || {
let mut num = data.lock().unwrap();
*num += 1;
});
handles.push(handle);
}
for handle in handles {
handle.join().unwrap();
}
println!("Final value: {}", *shared_data.lock().unwrap());
}
- 实现原理分析:
Arc
(原子引用计数):
Arc
用于在多个线程间共享数据。它提供了一种引用计数的方式来管理数据的生命周期。在这里,Arc<Mutex<i32>>
将Mutex<i32>
包装起来,使得多个线程可以持有对这个Mutex
的引用。
Mutex
:
Mutex
保护内部数据(这里是i32
类型的变量)。调用lock
方法时,会尝试获取锁。如果锁可用,则返回一个MutexGuard
智能指针,它实现了DerefMut
trait,允许对内部数据进行可变借用。
- 当
MutexGuard
离开作用域时(例如在let mut num = data.lock().unwrap();
语句块结束时),它会自动释放锁,这确保了同一时间只有一个线程可以访问和修改共享数据,从而避免数据竞争。
- 所有权和借用机制:
- Rust的所有权和借用机制在这个场景中起着关键作用。
MutexGuard
持有对Mutex
内部数据的可变借用,这符合Rust的规则:同一时间只能有一个可变借用,从而避免了未定义行为。同时,Arc
管理Mutex
的所有权,确保Mutex
在所有线程都使用完毕后才会被释放。