sho*_*app 5 multithreading rust
我是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
}
}
Run Code Online (Sandbox Code Playgroud)
我知道为什么由于函数use of moved value: self内部而导致错误start,但是我想知道如何设计我的结构,以便类似这样的工作。在我能想到的每种情况下,我总是会有双重借贷的情况。
我有一种直觉,我需要学习更多有关内部可变性的知识,但是我想我会先寻求设计指导,然后再进行更多研究。
我认为你已经很接近让它工作了。
只有两个障碍:
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();
}
Run Code Online (Sandbox Code Playgroud)
我邀请您一次一个地戳破它(即,更改与您的示例不同的一件事,检查错误消息,并尝试了解差异是如何解决它的)。
在操场上,它为我打印:
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!
Run Code Online (Sandbox Code Playgroud)
虽然我不会依赖(1)"Hello, World!"出现的次数和(2)"Feeling sleepy..."首先出现。
该死的,Atomic太冗长了......我有点希望有一个get/ setwith SeqCst(更强的排序)可用。
| 归档时间: |
|
| 查看次数: |
921 次 |
| 最近记录: |