我如何在一个对象内部模拟一个定时器,该定时器会定期使该对象发生变化? [英] How do I emulate a timer inside an object that will periodically mutate the object?

查看:74
本文介绍了我如何在一个对象内部模拟一个定时器,该定时器会定期使该对象发生变化?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的项目中,我需要做类似的事情:

use std::thread;
use std::time::Duration;

struct A {
    pub ints: Vec<u8>,
}

impl A {
    fn new() -> A {
        let mut a = A {
            ints: vec![1, 5, 6, 2, 3, 4],
        };
        a.timer();
        a
    }

    fn timer(&mut self) {
        thread::spawn(move || {
            loop {
                thread::sleep(Duration::from_millis(1));
                self.ints.remove(0);
            }
        });
    }
}

fn main() {
    let a = A::new();
    loop {
        println!("Remaining elements: {:?}", a.ints);
    }
}

这个想法是某些结构包含一个元素向量.这些元素应在一段时间后从向量中删除.可以将其视为一个定期计时器,该计时器检查某项并对可变对象执行操作(删除元素).如果删除正在处理该线程的对象,则也需要删除该线程.因此,我认为它应该是要操纵的结构的成员.

上面代码的问题是它有很多借用错误,我不知道该怎么做.

我很少看到这样的问题,但是每个问题都是关于在线程中处理标量的.之所以不能在此处应用它,是因为该线程应该是内部 A结构中的某个东西,并且应该在属于该结构成员的向量上调用remove. /p>

我想我应该使用Arc之类的东西,但我不太了解如何在这里使用它.

解决方案

我想我应该使用Arc或类似的东西,但是我不太了解如何在这里使用它.

实际上,这是最简单的解决方案:

您可以将ints字段包装在Arc中,但是随后您将无法修改Vec,因此也将其包装在Mutex中:

struct A {
    pub ints: Arc<Mutex<Vec<u8>>>,
}

然后,您可以克隆Arc以接收到同一内存的第二个句柄.

fn timer(&mut self) {
    let ints = self.ints.clone();
    thread::spawn(move || {
        loop {
            thread::sleep(Duration::from_millis(1));

而不是直接访问Vec,而是需要lock Mutex,如果在访问Mutex时另一个线程出现紧急情况,这可能会失败.

            ints.lock().unwrap().remove(0);
        }
    });
}

In my project I need to do something like:

use std::thread;
use std::time::Duration;

struct A {
    pub ints: Vec<u8>,
}

impl A {
    fn new() -> A {
        let mut a = A {
            ints: vec![1, 5, 6, 2, 3, 4],
        };
        a.timer();
        a
    }

    fn timer(&mut self) {
        thread::spawn(move || {
            loop {
                thread::sleep(Duration::from_millis(1));
                self.ints.remove(0);
            }
        });
    }
}

fn main() {
    let a = A::new();
    loop {
        println!("Remaining elements: {:?}", a.ints);
    }
}

The idea is that some struct contains a vector of elements. These elements should be removed from the vector after some period of time. Think of it as a periodic timer that checks something and performs an action on mutable object (removes an element). This thread also needs to be dropped if the object on which it is working on is deleted. So I guess it should be a member of a struct of which it is manipulating.

The problem with the code above is that it has a lot of borrow errors and I don't understand how to do that.

I have seen few questions like this but each of them was about manipulating scalar in a thread. The reason why I can't apply it here is because the thread should be something that is inside A struct and it should call remove on a vector that is a member of that struct.

I guess I should use Arc or something like that but don't really understand how to use it here.

解决方案

I guess I should use Arc or something like that but don't really understand how to use it here.

Indeed that is the simplest solution:

You can wrap the ints field in an Arc, but then you wouldn't be able to modify the Vec, so you also wrap it in a Mutex:

struct A {
    pub ints: Arc<Mutex<Vec<u8>>>,
}

Then you can clone the Arc to receive a second handle to the same memory.

fn timer(&mut self) {
    let ints = self.ints.clone();
    thread::spawn(move || {
        loop {
            thread::sleep(Duration::from_millis(1));

Instead of directly accessing the Vec, you then need to lock the Mutex, which can fail if another thread panicked while accessing the Mutex.

            ints.lock().unwrap().remove(0);
        }
    });
}

这篇关于我如何在一个对象内部模拟一个定时器,该定时器会定期使该对象发生变化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆