面试题答案
一键面试-
Sync
和Send
特性Send
特性:在Rust中,实现了Send
特性的类型可以安全地跨线程发送。大部分基本类型,如i32
、String
等都实现了Send
特性。这意味着可以将这些类型的数据通过通道(channel
)等方式发送到其他线程。Sync
特性:实现了Sync
特性的类型可以安全地在多个线程间共享。例如,&T
当T: Sync
时,&T
也实现了Sync
特性。这使得多个线程可以拥有指向同一个数据的不可变引用。
-
Arc
和Mutex
的作用Arc
(原子引用计数):Arc
用于在堆上分配数据,并允许多个Arc
实例指向同一个数据,通过引用计数来管理数据的生命周期。当最后一个Arc
实例被销毁时,数据才会被释放。它主要用于线程安全地共享数据,因为Arc
实现了Send
和Sync
特性。Mutex
(互斥锁):Mutex
用于保护数据,确保同一时间只有一个线程可以访问数据。它通过锁定机制来实现这一点,当一个线程获取了Mutex
的锁,其他线程就必须等待锁被释放才能访问数据。Mutex
也实现了Send
和Sync
特性。
-
实现思路
- 为了在多线程中安全地共享字符串数据,我们可以使用
Arc<Mutex<String>>
。Arc
确保字符串数据可以在多个线程间安全共享,Mutex
确保同一时间只有一个线程可以修改字符串。 - 当一个线程需要读取或修改字符串时,它首先需要获取
Mutex
的锁。如果锁不可用,线程会被阻塞,直到锁可用。
- 为了在多线程中安全地共享字符串数据,我们可以使用
-
关键代码示例
use std::sync::{Arc, Mutex};
use std::thread;
fn main() {
let shared_string = Arc::new(Mutex::new(String::from("initial value")));
let mut handles = vec![];
for _ in 0..10 {
let string_clone = Arc::clone(&shared_string);
let handle = thread::spawn(move || {
let mut string = string_clone.lock().unwrap();
string.push_str(" modified by thread");
});
handles.push(handle);
}
for handle in handles {
handle.join().unwrap();
}
let final_string = shared_string.lock().unwrap();
println!("Final string: {}", final_string);
}
在上述代码中:
- 首先创建了一个
Arc<Mutex<String>>
类型的shared_string
。 - 然后在一个循环中创建了10个线程,每个线程克隆一份
Arc
并获取Mutex
的锁,修改字符串。 - 主线程等待所有子线程完成后,再次获取锁并打印最终的字符串。