使用 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

Playground

其实我有一个想法。如果我使用 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].