在 [Rust 檔案][1] 的以下代碼中,它討論了 Rust 中的并發執行緒。
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!("Result: {}", *counter.lock().unwrap());
}
我仍然無法理解手柄的 for 回圈的想法
IE
for handle in handles {
handle.join().unwrap();
}
檔案說“我們在每個句柄上呼叫 join 以確保所有執行緒都完成。” 對于一個實驗,我注釋掉了回圈句柄,我得到了 8 而不是 10 的輸出。當我將回圈更改為 1000 時,我注釋句柄回圈時得到 999。這里發生了什么?8 & 999 如何成為輸出?
[1]: https://doc.rust-lang.org/book/ch16-03-shared-state.html
uj5u.com熱心網友回復:
我仍然無法理解手柄的 for 回圈的想法
有什么要把握的?JoinHandle::join阻塞,直到相應的執行緒完成執行(所以函式已經結束),這就是它的大部分內容(有用的是它也產生執行緒函式回傳的任何東西)。
當我將回圈更改為 1000 時,當句柄回圈被注釋時,我得到 999。這里發生了什么?8 & 999 如何成為輸出?
當您不在join執行緒上時,您會在執行緒和主執行緒(main函式)之間進行競爭。你得到的值是多少執行緒在它花費的時間內執行了增量
- 創建所有執行緒
- 將每個執行緒添加到向量
- 在柜臺上鎖
這將根據系統負載和作業系統調度細節而改變,盡管主執行緒的大部分延遲將是......產生更多執行緒(與產生執行緒相比,獲取鎖和增加一個數字很便宜)這就是為什么大多數的執行緒在您列印結果時完成。如果您增加每個執行緒的作業量,或更改執行緒的生成方式,您將看到不同的競賽。
uj5u.com熱心網友回復:
join ()所做的只是等待執行緒完成。它要求作業系統阻塞主執行緒(呼叫者join()),直到加入的執行緒完成,并收集其狀態。
在呼叫之前join(),你只知道你已經將執行緒交給了作業系統。稍后在代碼中您不知道它是否已經啟動、正在運行、已完成、被作業系統殺死或已恐慌()等。
counter在呼叫之前,您對共享的唯一了解join()是您可??以以一致的狀態讀取它(感謝互斥鎖)。也就是說,不會冒主執行緒和可能正在遞增它的另一個執行緒之間的競爭條件的風險。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/521473.html
標籤:多线程锈并发互斥体
上一篇:JavaSpringBoot中如何通過接收引數來命名執行緒?
下一篇:彼得森的解決方案只使用一個變數
