线程引用需要静态生存期吗? [英] Thread references require static lifetime?
问题描述
从直觉上讲,传递给派生线程的引用需要具有静态生存期,但我不清楚究竟是什么导致以下代码无法编译:
While it makes sense intuitively that references passed to spawned threads need to have static lifetimes, I'm unclear about what exactly is making the following code not compile:
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));
}
}
}
编译此小程序会出现以下错误:
Compiling this small program gives the following error:
$ 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
,在这种情况下,这很重要...?希望有人可以帮助我了解我的缺失!
It seems to me that the variable a
will out-live c_clone
, which is what matters in this case...? Hopefully someone can help me understand what I'm missing!
推荐答案
本质上,Arc
和Mutex
包装是多余的:您正在传递对本地堆栈上的内容的引用.当您使用std::thread::spawn
生成线程时,没有任何将生存期链接在一起的内容.主线程可以自由地结束并释放其中的任何内容(在这种情况下,包括a
在内),甚至可以在其他线程生成之前甚至执行 start 来释放它.因此,在这种情况下,a
可以在生成的线程执行任何操作时引用释放的内存,而将c_clone
保留为悬空指针.这就是为什么生成的线程关闭的环境必须为'static
In its essence, the Arc
and Mutex
wrapping is superfluous: you are passing a reference to something on the local stack. When you spawn a thread with std::thread::spawn
, there is nothing linking the lifetimes together; the main thread is quite at liberty to conclude and free anything in it—in this case, including a
—before any other threads it spawns even start executing; thus in this case a
could refer to freed memory by the time the spawned thread does anything, leaving c_clone
as a dangling pointer. This is why the environment of the closure of a spawned thread must be 'static
.
这篇关于线程引用需要静态生存期吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!