我正在做一個簡單的程式來模擬超市排隊來學習 Rust。該程式包含兩個執行緒。一種是將人員(char 'x')添加到超市佇列中,另一種是洗掉他們。
我使用 Arc 和 Mutex 來處理并發,但似乎第一個執行緒永遠不會釋放 var,所以第二個執行緒不起作用。
代碼如下:
let queue = Arc::new(Mutex::new(Vec::<char>::new()));
let queue1 = Arc::clone(&queue);
thread::spawn(move || loop {
let mut aux = queue1.lock().unwrap();
aux.push('x');
print_queue(&aux);
thread::sleep(Duration::from_secs(3));
});
thread::spawn(move || loop {
let mut aux = queue.lock().unwrap();
println!("AUX state: {:?}", aux);
if !&aux.is_empty() {
aux.pop();
}
print_queue(&aux);
let mut rng = rand::thread_rng();
thread::sleep(Duration::from_secs(rng.gen_range(1..10)));
});
AUX 狀態的列印永遠不會顯示。我做錯了什么?
uj5u.com熱心網友回復:
您的代碼正在使用這種模式:
loop {
let mut guard = mutex.lock().unwrap();
// do something with `guard`
thread::sleep(duration);
// `guard` is implicitly dropped at the end of the scope
}
這段代碼的問題是互斥守衛(在這種情況下guard)持有鎖,并一直持有直到它被洗掉,在這種情況下,當變數超出范圍時就會發生這種情況。但是在執行緒休眠后它會超出范圍,因此執行緒在休眠時仍然會持有鎖。
為避免這種情況,您應該在使用完畢后立即放下防護,在執行緒休眠之前:
loop {
{
let mut guard = mutex.lock().unwrap();
// do something with `guard`
// implicitly drop `guard` at the end of the inner scope, before sleep
}
thread::sleep(duration);
}
或者
loop {
let mut guard = mutex.lock().unwrap();
// do something with `guard`
// explicitly drop `guard` before sleep
drop(guard);
thread::sleep(duration);
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/529410.html
標籤:多线程锈
上一篇:新執行緒上的C SIGABRT
下一篇:執行緒鎖定似乎無法始終如一地作業
