面试题答案
一键面试创建新线程并传递数据
在Rust中使用std::thread
创建新线程并传递数据可以通过以下方式:
use std::thread;
fn main() {
let data = String::from("Hello, thread!");
let handle = thread::spawn(move || {
println!("Thread received data: {}", data);
});
handle.join().unwrap();
}
在上述代码中:
- 定义了一个
data
变量,类型为String
。 - 使用
thread::spawn
创建新线程,并通过闭包捕获data
。这里使用move
关键字,它将data
的所有权转移到新线程中。
处理线程间资源竞争问题及同步机制
- 互斥锁(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!("Final counter value: {}", *counter.lock().unwrap());
}
- 在这个例子中,
Arc<Mutex<i32>>
用于在多个线程间共享计数器。Mutex
确保每次只有一个线程能修改计数器的值。lock
方法返回一个MutexGuard
,它在作用域结束时自动释放锁。
- 读写锁(RwLock):
- 当有多个线程频繁读取共享资源,而写操作较少时,使用读写锁更合适。它允许多个线程同时读,但只允许一个线程写。
- 示例:
use std::sync::{Arc, RwLock};
use std::thread;
fn main() {
let data = Arc::new(RwLock::new(String::from("initial data")));
let mut handles = vec![];
for _ in 0..3 {
let data = Arc::clone(&data);
let handle = thread::spawn(move || {
let read_data = data.read().unwrap();
println!("Read data: {}", read_data);
});
handles.push(handle);
}
let data = Arc::clone(&data);
let write_handle = thread::spawn(move || {
let mut write_data = data.write().unwrap();
*write_data = String::from("new data");
});
handles.push(write_handle);
for handle in handles {
handle.join().unwrap();
}
let final_data = data.read().unwrap();
println!("Final data: {}", final_data);
}
- 这里
Arc<RwLock<String>>
用于共享数据。读操作使用read
方法获取RwLockReadGuard
,写操作使用write
方法获取RwLockWriteGuard
。
- 条件变量(Condvar):
- 条件变量用于线程间的同步通信。一个线程可以等待某个条件满足,而其他线程可以通知等待的线程条件已经满足。
- 示例:
use std::sync::{Arc, Mutex};
use std::sync::Condvar;
use std::thread;
fn main() {
let pair = Arc::new((Mutex::new(false), Condvar::new()));
let pair2 = Arc::clone(&pair);
let handle = 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!("Condition met!");
handle.join().unwrap();
}
- 在这个例子中,一个线程等待条件变量
cvar
的通知,另一个线程设置条件并通知等待的线程。wait
方法会释放锁并阻塞线程,直到收到通知。收到通知后,它重新获取锁并返回。