设计思路
- 使用互斥锁(Mutex)和条件变量(Condvar):互斥锁用于保护共享状态,条件变量用于线程间的同步。主线程和工作线程通过共享的状态和条件变量进行通信。
- 共享状态:定义一个结构体来表示共享状态,其中包含一个布尔标志,用于指示主线程是否发出了信号,以及一个计数器,用于记录工作线程完成任务的数量。
- 工作线程:工作线程在启动时等待主线程的信号,信号发出后执行任务,完成任务后通知主线程。
- 主线程:主线程设置信号,等待工作线程完成任务。
代码实现
use std::sync::{Arc, Condvar, Mutex};
use std::thread;
// 共享状态结构体
struct SharedState {
signal: bool,
completed_count: u32,
}
fn main() {
let shared_state = Arc::new((Mutex::new(SharedState {
signal: false,
completed_count: 0,
}), Condvar::new()));
let mut handles = Vec::new();
let num_workers = 3;
for _ in 0..num_workers {
let shared_state_clone = shared_state.clone();
let handle = thread::spawn(move || {
let (lock, cvar) = &*shared_state_clone;
let mut state = lock.lock().unwrap();
// 等待主线程的信号
while!state.signal {
state = cvar.wait(state).unwrap();
}
// 模拟工作
println!("Worker started working");
thread::sleep(std::time::Duration::from_secs(1));
println!("Worker finished working");
state.completed_count += 1;
cvar.notify_one();
});
handles.push(handle);
}
// 主线程设置信号
let (lock, cvar) = &*shared_state;
let mut state = lock.lock().unwrap();
state.signal = true;
cvar.notify_all();
// 主线程等待所有工作线程完成
while state.completed_count < num_workers as u32 {
state = cvar.wait(state).unwrap();
}
for handle in handles {
handle.join().unwrap();
}
}
关键部分作用
- SharedState结构体:用于存储共享状态,
signal
表示主线程是否发出信号,completed_count
记录工作线程完成任务的数量。
- Arc<(Mutex, Condvar)>:使用
Arc
来实现跨线程的共享所有权,Mutex
用于保护 SharedState
,Condvar
用于线程间同步。
- 工作线程中的
while!state.signal
循环:工作线程在启动时等待主线程的信号,cvar.wait(state)
会释放锁并阻塞线程,直到收到通知。
- 主线程中的
state.signal = true; cvar.notify_all();
:主线程设置信号并通知所有工作线程。
- 主线程中的
while state.completed_count < num_workers as u32
循环:主线程等待所有工作线程完成任务,cvar.wait(state)
会阻塞主线程,直到工作线程完成任务并通知。