在生锈的线程内访问一种自我方法



我想将 self struct对象传播到线程中,然后调用其增加HMS时间的time_tick()方法。

pub fn start(&mut self) {
    self.acti = true;   // the time tick is activated now...
    thread::spawn(move || {
        let local_self: *mut Self = self;   // this self live in the thread
        loop {
            thread::sleep(Duration::from_secs(1));  // wait for 1 sec
            if (*local_self).acti == true { (*local_self).time_tick(); }    
            (*local_self).print_time();  // for debug
        }
    });
}

我收到错误消息:

error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
  --> src/hmstimer/mod.rs:42:17
   |
42 |           thread::spawn(move || {
   |  _______________________^
43 | |             let local_self: *mut Self = self;   // this self live in the thread
44 | |             loop {
45 | |                 thread::sleep(Duration::from_secs(1));    // wait for 1 sec
...  |
48 | |             }
49 | |         });
   | |_________^
   |
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 40:2...
  --> src/hmstimer/mod.rs:40:2
   |
40 |       pub fn start(&mut self) {
   |  _____^
41 | |         self.acti = true;    // the time tick is activated now...
42 | |         thread::spawn(move || {
43 | |             let local_self: *mut Self = self;   // this self live in the thread
...  |
49 | |         });
50 | |     }
   | |_____^
   = note: ...so that the types are compatible:
           expected &mut hmstimer::HMSTimer
              found &mut hmstimer::HMSTimer
   = note: but, the lifetime must be valid for the static lifetime...
note: ...so that the type `[closure@src/hmstimer/mod.rs:42:17: 49:7 self:&mut hmstimer::HMSTimer]` will meet its required lifetime bounds

,但似乎关于方法是不合适的。完成任务的最佳做法是什么?

您无法通过捕获thread::spawn的可变引用的闭合。thread::spawn需要该功能为'static,这意味着它不会捕获任何借款,或者所有借口都是'static。那是因为在删除指南后,线程可以继续运行。

如果您不需要在调用start之后在原始线程中使用self,则可以按值传递self

pub fn start(self) {
    self.acti = true;
    thread::spawn(move || {
        loop {
            thread::sleep(Duration::from_secs(1));
            if self.acti == true { self.time_tick(); }    
            self.print_time();
        }
    });
}

否则,您需要使用Arc来获取两个线程以共享Self的所有权,以及MutexRwLock来同步读取和跨线程。

// note: this is not a method anymore;
// invoke as `HMSTimer::start(arc.clone());`
pub fn start(this: Arc<Mutex<Self>>) {
    this.lock().expect("mutex is poisoned").acti = true;
    thread::spawn(move || {
        loop {
            thread::sleep(Duration::from_secs(1));
            let lock = this.lock().expect("mutex is poisoned");
            if lock.acti == true { lock.time_tick(); }    
            lock.print_time();
            // `lock` is dropped here, unlocking the mutex
        }
    });
}

相关内容

最新更新