2015-10-06 55 views
1

雖然它是有道理直觀地傳遞給產生的線程引用需要具有靜態的壽命,我不清楚究竟是什麼使下面的代碼無法編譯:線程引用需要靜態生命週期?

use std::sync::Arc; 
use std::sync::Mutex; 

struct M; 

fn do_something(m : Arc<Mutex<&M>>) { 
    println!("Ha, do nothing!"); 
} 

fn main() { 
    let a = M; 
    { 
     let c : Arc<Mutex<&M>> = Arc::new(Mutex::new(&a)); 
     for i in 0..2 { 
      let c_clone = c.clone(); 
      ::std::thread::spawn(move || do_something(c_clone)); 
     } 
    } 
} 

編譯這個小程序提供了以下錯誤:

$ rustc -o test test.rs 
test.rs:13:55: 13:56 error: `a` does not live long enough 
test.rs:13   let c : Arc<Mutex<&M>> = Arc::new(Mutex::new(&a)); 
                  ^
note: reference must be valid for the static lifetime... 

在我看來,這個變量a會出現場c_clone,這是在這種情況下,什麼事情...?希望有人能幫助我理解我錯過的東西!

+0

線程可以從其他線程啓動。沒有辦法靜態地知道哪個線程正在產生線程,所以保守的(read * safe *)解決方案是要求所有的引用必須具有'靜態生命週期。在'main'中創建的項目沒有這個生命週期,因爲它們在主要退出之前被銷燬。 – Shepmaster

回答

5

其實質上,ArcMutex包裝是多餘的:您傳遞對本地堆棧上某些東西的引用。當你用std::thread::spawn產生一個線程時,沒有任何東西在一起,主線程完全可以自由地斷定並釋放其中的任何東西 - 在這種情況下,包括a - 在它產生的任何其他線程之前,甚至可以執行開始執行;因此在這種情況下,當產生的線程執行任何操作時,a可能引用釋放的內存,將c_clone作爲懸掛指針。這就是爲什麼產生的線程關閉的環境必須是'static

+0

[這裏是參考](https://doc.rust-lang.org/std/thread/fn.spawn.html)到'std :: thread :: spawn'的文檔 – Mokosha