我想将 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
的所有权,以及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
}
});
}