use std::ops::Deref;
use std::sync::{Arc, Mutex, MutexGuard};
struct Var {}
fn multithreading() -> Var {
let shared_var = Arc::new(Mutex::new(Var {}));
/*
multithreading job
*/
return *(shared_var.lock().unwrap().deref());
}
我正在定義一個多執行緒函式來操作,Var但這個函式沒有編譯和抱怨:
error[E0507]: cannot move out of a shared reference
有沒有辦法停止共享shared_var并回傳其中的變數?
實作 trait CopyforVar也可能解決這個錯誤,但在我的實際用例中,Var它太大而無法復制,我更喜歡任何其他解決方案。
uj5u.com熱心網友回復:
這里的問題是,如果你Var從共享變數中洗掉你的,會留下什么?如果您的任何其他副本Arc留在某處并嘗試訪問現在已洗掉的物件,會發生什么情況?
這個問題有幾個可能的答案:
1.我肯定沒有其他強參考,這是最后一個Arc。如果沒有,讓它恐慌。
如果是這種情況,您可以使用Arc::try_unwrap()來獲取內部互斥鎖。然后另一個into_inner()來獲得真正的價值。
let mutex = Arc::try_unwrap(shared_var).unwrap();
mutex.into_inner().unwrap()
請注意,為了使這些Result::unwrap()作業,您的型別必須實作Debug,出于...原因。如果沒有,您可以使用一match/panic!對。
2. 可能還有其他強參考副本Arc,反正我想偷物件。
然后你必須在它的位置放一些東西。顯而易見的解決方案是存盤一個Option<Var>替代并用于Option::take()竊取值:
let shared_var = Arc::new(Mutex::new(Some(Var {})));
/*
multithreading job
*/
let mut lck = shared_var.lock().unwrap();
lck.take().unwrap()
現在,此共享值的任何其他用途都必須檢查該選項,以防萬一None。
3. 可能還有其他副本Arc但我不想處理Option<Var>.
但是你必須在那里留下一些東西!也許您可以在其位置插入一個虛擬物件。如果您的Var工具Default可以使用std::mem::take():
let mut lck = shared_var.lock().unwrap();
std::mem::take(&mut *lck)
如果它沒有實作,Default但您可以廉價地創建一個空物件,請std::mem::replace()改用:
let mut lck = shared_var.lock().unwrap();
std::mem::replace(&mut *lck, Var{})
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/382676.html
上一篇:使用執行緒時如何減少時間偏差?
下一篇:使用執行緒連接的目的是什么
