我不确定我是否了解Rust Mutex
es和条件变量的并发支持。在下面的代码中,main
线程将poll_thread
设置为空闲两秒钟,然后设置为"读取寄存器"持续2秒,然后返回"空闲":
use std::thread;
use std::sync::{Arc, Mutex, Condvar};
use std::time;
#[derive(PartialEq, Debug)]
enum Command {
Idle,
ReadRegister(u32),
}
fn poll_thread(sync_pair: Arc<(Mutex<Command>, Condvar)>) {
let &(ref mutex, ref cvar) = &*sync_pair;
loop {
let mut flag = mutex.lock().unwrap();
while *flag == Command::Idle {
flag = cvar.wait(flag).unwrap();
}
match *flag {
Command::Idle => {
println!("WHAT IMPOSSIBLE!");
panic!();
}
Command::ReadRegister(i) => {
println!("You want me to read {}?", i);
thread::sleep(time::Duration::from_millis(450));
println!("Ok, here it is: {}", 42);
}
}
}
}
pub fn main() {
let pair = Arc::new((Mutex::new(Command::Idle), Condvar::new()));
let pclone = pair.clone();
let rx_thread = thread::spawn(|| poll_thread(pclone));
let &(ref mutex, ref cvar) = &*pair;
for i in 0..10 {
thread::sleep(time::Duration::from_millis(500));
if i == 4 {
println!("Setting ReadRegister");
let mut flag = mutex.lock().unwrap();
*flag = Command::ReadRegister(5);
println!("flag is = {:?}", *flag);
cvar.notify_one();
} else if i == 8 {
println!("Setting Idle");
let mut flag = mutex.lock().unwrap();
*flag = Command::Idle;
println!("flag is = {:?}", *flag);
cvar.notify_one();
}
}
println!("after notify_one()");
rx_thread.join();
}
这可以按预期工作,但是当取消注释450毫秒的睡眠线时,代码通常会保留在&#34; read&#34;状态而不是返回等待条件变量cvar.wait()
。有时它会在15秒后恢复闲置!
我认为当poll_thread
到达loop
的底部时,它会释放锁定,允许main
获取并设置flag = Command::Idle
,大约一半第二个,poll_thread
将返回空闲状态,但似乎poll_thread
睡眠时不会发生这种情况。为什么呢?