Доступ к методу self внутри потока в Rust - PullRequest
0 голосов
/ 03 марта 2019

Я хочу распространить объект структуры self в поток, а затем вызвать его time_tick() метод для увеличения времени HMS.

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

Но, похоже, метод about не подходит.Как лучше всего выполнять задание?

1 Ответ

0 голосов
/ 03 марта 2019

Вы не можете передать закрытие, которое фиксирует изменчивую ссылку на thread::spawn.thread::spawn требуется, чтобы эта функция была 'static, что означает, что либо она не захватывает заимствования, либо все заимствования равны 'static.Это связано с тем, что поток может продолжать работать после удаления референта.

Если вам не нужно использовать self в исходном потоке после вызова start, тогда вы можете просто передать self с помощьюvalue.

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, а также Mutex или RwLock для синхронизации операций чтения и записи между потоками.

// 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
        }
    });
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...