我正在做rust book 的最后一個專案(第 20 章 - 構建多執行緒 Web 服務器),執行緒作業者的最終作業代碼是:
impl Worker {
fn new(id: usize, receiver: Arc<Mutex<mpsc::Receiver<Message>>>) -> Worker {
let thread = thread::spawn(move || loop {
let message = receiver.lock().unwrap().recv().unwrap();
match message {
Message::NewJob(job) => {
println!("Worker {} got a job; executing.", id);
job();
}
Message::Terminate => {
println!("Worker {} was told to terminate.", id);
break;
}
}
});
// ...
}
}
然后我決定通過洗掉message變數來縮短代碼并直接應用匹配運算子receiver.lock().unwrap().recv().unwrap()
impl Worker {
fn new(id: usize, receiver: Arc<Mutex<mpsc::Receiver<Message>>>) -> Worker {
let thread = thread::spawn(move || loop {
match receiver.lock().unwrap().recv().unwrap() {
Message::NewJob(job) => {
println!("Worker {} got a job; executing.", id);
job();
}
Message::Terminate => {
println!("Worker {} was told to terminate.", id);
break;
}
}
});
// ...
}
}
但是現在只有一個工人(第一個)回應作業佇列。
這里發生了什么?
uj5u.com熱心網友回復:
這兩個代碼片段不等效。不同之處在于借用和丟棄臨時工的方式。
在第一個示例中,臨時互斥鎖在陳述句末尾被洗掉:
let message = receiver.lock().unwrap().recv().unwrap();
// the mutex guard is dropped here, and other threads can acquire the lock
而在第二次被剪斷時,互斥鎖保持活動狀態并因此保持鎖定直到match陳述句結束:
match receiver.lock().unwrap().recv().unwrap() { // the mutex is locked here and will remain locked until the channel yields a result, thus blocking other threads
Message::NewJob(job) => {
println!("Worker {} got a job; executing.", id);
job();
}
Message::Terminate => {
println!("Worker {} was told to terminate.", id);
break;
}
}
// the mutex guard is dropped here
因此,在第二個示例中,其他執行緒被鎖定,無法獲取對通道接收端的訪問。
參考此執行緒的答案:
當在運算式中創建臨時變數時,它(僅)被丟棄在 enscoping 陳述句的末尾:
- let 系結在系結(“變數”)可用之前結束其陳述句;
- 匹配和派生,在系結(“變數”)可用的范圍之后結束陳述句。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/447426.html
上一篇:我如何使這個程式執行緒安全,通道是最好的實作,如果是,如何?
下一篇:Prologue-Webframework-使用`--threads:on`標志編譯時如何設定執行緒區域變數進行日志記錄?
