使用 arc mutex 生成线程时的生命周期问题
Lifetime problem when spawning a thread with arc mutex
我不明白为什么下面的代码会失败
use std::sync::{Arc};
use futures::lock::Mutex;
struct A<'a>{
a: &'a u8
}
impl<'a> A<'a>{
pub fn run(a: Arc<Mutex<Self>>) {
let stack_thread = std::thread::Builder::new()
.spawn(move || {
let a = a.clone();
}).unwrap();
}
}
错误:
error[E0477]: the type `[closure@src/lib.rs:11:20: 13:14]` does not fulfill the required lifetime
--> src/lib.rs:11:14
|
11 | .spawn(move || {
| ^^^^^
|
= note: type must satisfy the static lifetime
其实我有一个想法。如果我使用 A
的生命周期并删除 a
成员,它就可以工作。所以它可能在生成的线程中拒绝 a: Arc<Mutex<Self>>
。生成线程时,闭包必须具有静态生命周期:
pub fn spawn<F, T>(f: F) -> JoinHandle<T>
where F: FnOnce() -> T,
F: Send + 'static,
T: Send + 'static
所以看起来 a
是在闭包内部传递的,这使得闭包不是 'static
。但我不明白为什么,因为线程内部的 a: Arc<Mutex<Self>>
与关闭一样长。有人可以详细解释发生了什么吗?我将事物的生命周期与引用的生命周期等混淆了。
虽然 Arc<Mutex<Self>>
被移动到闭包中并且只要闭包存在就一直存在(删除闭包会删除 Arc
),但这在这里是不够的。正如您在文档中看到的那样,新生成的线程可以永远存在 ('static
),并且它要求传入的闭包为 'static
。但是只是将一些东西包装成 Arc
并不能使那个东西 'static
:
如果我给你一些通用的 A<'a>
,作为 Arc<Mutex<Self>>
的一部分,任何生命周期 'a
,生命周期 'a
可能比 'static
.如果你把这个 A<'a>
放到一个 Arc
中并传递下去,生命周期 'a
的东西(在这种情况下是 a
-成员)的破坏将使 [= 26=、Mutex<A>
和 Arc<Mutex<A>>
无效。
实际上:通用生命周期不能通过将它们包装在原子原语中来“解决”,因为它们不能强制其居民 'static
生命周期。
您要找的是
impl A<'static>{
pub fn run(a: Arc<Mutex<Self>>) {
let stack_thread = std::thread::Builder::new()
.spawn(move || {
let a = a.clone();
}).unwrap();
}
}
或者您需要将 A
的定义更改为 'static
在任何情况下,例如通过持有 Box<[u8]>
而不是 &'a [u8]
.
我不明白为什么下面的代码会失败
use std::sync::{Arc};
use futures::lock::Mutex;
struct A<'a>{
a: &'a u8
}
impl<'a> A<'a>{
pub fn run(a: Arc<Mutex<Self>>) {
let stack_thread = std::thread::Builder::new()
.spawn(move || {
let a = a.clone();
}).unwrap();
}
}
错误:
error[E0477]: the type `[closure@src/lib.rs:11:20: 13:14]` does not fulfill the required lifetime
--> src/lib.rs:11:14
|
11 | .spawn(move || {
| ^^^^^
|
= note: type must satisfy the static lifetime
其实我有一个想法。如果我使用 A
的生命周期并删除 a
成员,它就可以工作。所以它可能在生成的线程中拒绝 a: Arc<Mutex<Self>>
。生成线程时,闭包必须具有静态生命周期:
pub fn spawn<F, T>(f: F) -> JoinHandle<T>
where F: FnOnce() -> T,
F: Send + 'static,
T: Send + 'static
所以看起来 a
是在闭包内部传递的,这使得闭包不是 'static
。但我不明白为什么,因为线程内部的 a: Arc<Mutex<Self>>
与关闭一样长。有人可以详细解释发生了什么吗?我将事物的生命周期与引用的生命周期等混淆了。
虽然 Arc<Mutex<Self>>
被移动到闭包中并且只要闭包存在就一直存在(删除闭包会删除 Arc
),但这在这里是不够的。正如您在文档中看到的那样,新生成的线程可以永远存在 ('static
),并且它要求传入的闭包为 'static
。但是只是将一些东西包装成 Arc
并不能使那个东西 'static
:
如果我给你一些通用的 A<'a>
,作为 Arc<Mutex<Self>>
的一部分,任何生命周期 'a
,生命周期 'a
可能比 'static
.如果你把这个 A<'a>
放到一个 Arc
中并传递下去,生命周期 'a
的东西(在这种情况下是 a
-成员)的破坏将使 [= 26=、Mutex<A>
和 Arc<Mutex<A>>
无效。
实际上:通用生命周期不能通过将它们包装在原子原语中来“解决”,因为它们不能强制其居民 'static
生命周期。
您要找的是
impl A<'static>{
pub fn run(a: Arc<Mutex<Self>>) {
let stack_thread = std::thread::Builder::new()
.spawn(move || {
let a = a.clone();
}).unwrap();
}
}
或者您需要将 A
的定义更改为 'static
在任何情况下,例如通过持有 Box<[u8]>
而不是 &'a [u8]
.