2017-06-01 39 views
0

我正在使用使用事件循環的discord箱。我需要同時檢查事件,而我是把用戶輸入:通過互斥體訪問事件循環

let clone = context.clone(); 
thread::spawn(
    move || loop { 
     match clone.lock().unwrap().gateway.recv_event() { 
      Ok(event) => { 
       // println!("Updating state: {:?}", event); 
       clone.lock().unwrap().state.update(&event) 
      }, 
      Err(err) => { 
       stderr!("Error receiving: {}", err); 
      }, 
     } 
    } 
); 

這不工作,因爲它保持鎖定......那麼,關於

println!("Locking"); 
let mut gateway = { 
    &mut clone.lock().unwrap().gateway 
}; 
println!("Unlocked? {:?}", clone); 
match gateway.recv_event() { 
    Ok(event) => { 

這也似乎不上班:

Locking 
Unlocked? Mutex { <locked> } 

這將如何解決?

在我看來,如果有一種方法可以在不鎖定的情況下訪問互斥鎖的內容,那可能是最好的。

Example in Playground

The original question is here on reddit.

回答

1

我建議你閱讀再次Mutex什麼鎖保護罩(另見Borrow data out of a mutex "borrowed value does not live long enough",其中有一個類似的問題)。問題是,clone.lock().unwrap().gateway.recv_event()創建一個互斥鎖保護,直到完整的match聲明保留。例如,讓我們重新定義Something

#[derive(Debug)] 
struct Something(i32); 

impl Something { 
    pub fn get_some_event(&self) -> i32 { 
     thread::sleep(Duration::from_secs(1)); 
     self.0 
    } 
} 

此代碼:

let variable = Mutex::new(Something(4)); 
match variable.lock().unwrap().get_some_event() 
{ 
    5 => { 
     variable.lock().unwrap(); 
    } 
    _ => { 
     println!("{:?}", variable); // Still locked 
    } 
} 
println!("{:?}", variable); // no longer locked! 

但是這一次導致死鎖(因爲鏽標準互斥是不可重入):

let variable = Mutex::new(Something(5)); 
match variable.lock().unwrap().get_some_event() 
{ 
    5 => { 
     variable.lock().unwrap(); // deadlock! 
    } 
    _ => { 
     println!("{:?}", variable); 
    } 
} 
println!("{:?}", variable); 

解決方案在於,您只需在獲取事件時(或在執行其他操作時)需要鎖定。雖然不這樣做,請確保相應的鎖被丟棄。

let r = clone.lock().unwrap().gateway.recv_event(); // get result + drop lock 
match event { 
    Ok(event) => { 
     clone.lock().unwrap().state.update(&event) // also ok 
    }, 
    ... 
} 
+0

非常感謝您的回答!但是,問題是recv_event是需要時間的事情,但我需要同時使用它。 – jD91mZM2

+0

@ LEGOlord208我不明白你的意思。同時調用'&mut self'方法的唯一安全方法是使用同步機制,例如'Mutex'。考慮改進您的問題以適應其他要求。 –

+0

Ooooooooohhhhhhhhhhhhhhhhhhhh呃,我想你剛剛解決了它。也許它不一定是可變的!勒姆檢查。 aww廢話。如果這是不可能的,那麼我可能會提出一個拉動請求,以使得它不可變,如果可能的話。 – jD91mZM2