我是Rust的新手。作为一个学习练习,我正在尝试编写一个我曾用C ++编写的简单计时器结构。接口和实现看起来像这样:
pub struct Timer {
handle: Option<std::thread::JoinHandle<()>>,
alive: bool,
}
impl Timer {
pub fn new() {
Timer {
handle: None,
alive: false,
}
}
pub fn start(&'static mut self) {
// Oops! How do I do this?
self.handle = Some(std::thread::spawn(move || {
self.alive = true;
self.loop()
}));
}
pub fn stop(&mut self) {
self.alive = false;
self.handle.unwrap().join()
}
pub fn loop(&self) {
// while alive
}
}
我理解为什么这是一个错误,因为use of moved value: self
函数中的start
,但我想知道我应该如何设计我的结构这样的东西这样会起作用。在我能想到的每一个场景中,我总会有双重借款的情况。
我有一种预感,我需要了解更多关于室内可变性的内容,但我认为在再下一个兔子洞之前我会要求设计指导。
答案 0 :(得分:2)
我认为你非常接近让它发挥作用。
只有两个障碍:
thread::spawn
将不允许分享参考alive
和loop
让您分享此设计解决方案有两个方面:
Timer
)和工作人员(关闭)Arc
在两者之间共享状态,因为禁止引用以下是玩具的最小例子:
use std::{sync, thread, time};
use std::sync::atomic::{AtomicBool, Ordering};
pub struct Timer {
handle: Option<thread::JoinHandle<()>>,
alive: sync::Arc<AtomicBool>,
}
impl Timer {
pub fn new() -> Timer {
Timer {
handle: None,
alive: sync::Arc::new(AtomicBool::new(false)),
}
}
pub fn start<F>(&mut self, fun: F)
where F: 'static + Send + FnMut() -> ()
{
self.alive.store(true, Ordering::SeqCst);
let alive = self.alive.clone();
self.handle = Some(thread::spawn(move || {
let mut fun = fun;
while alive.load(Ordering::SeqCst) {
fun();
thread::sleep(time::Duration::from_millis(10));
}
}));
}
pub fn stop(&mut self) {
self.alive.store(false, Ordering::SeqCst);
self.handle
.take().expect("Called stop on non-running thread")
.join().expect("Could not join spawned thread");
}
}
fn main() {
let mut timer = Timer::new();
timer.start(|| println!("Hello, World!") );
println!("Feeling sleepy...");
thread::sleep(time::Duration::from_millis(100));
println!("Time for dinner!");
timer.stop();
}
我邀请您一次戳一个洞(即,更改一个与您的示例不同的内容,检查错误消息,并尝试了解差异是如何解决的)。
在操场上,它为我打印:
Feeling sleepy...
Hello, World!
Hello, World!
Hello, World!
Hello, World!
Hello, World!
Hello, World!
Hello, World!
Hello, World!
Hello, World!
Hello, World!
Time for dinner!
虽然我不会依赖(1)"Hello, World!"
出现的次数和(2)"Feeling sleepy..."
出现的次数。
该死的,Atomic
详细...我希望有一个get
/ set
SeqCst
(更强的排序)。< / em>的