rust学习(模拟Future)

一.future结构体

rust 复制代码
//声明
trait DefaultValue {//1
    fn getDefault()->Self;
}
struct MFuture<T> where T:DefaultValue + Copy{
    mutex:Mutex<(bool,T)>,//2
    cond:Condvar//3
}

struct MTask<T> where T:DefaultValue + Copy{
    future:Arc<MFuture<T>>,//4
    func:Box<dyn Fn()-> T + 'static + Send>,//5
}
//实现
impl DefaultValue for i32 {//6
    fn getDefault()->Self {
        0
    }
}

1.DefaultValue主要是为了初始化future的时候默认值需要赋值。没有办法,强行加了一个这个接口。

2.MFuture::mutex主要存储了一个元,包含了(是否完成,结果)这2项目

3.MFuture::cond主要是用来通知wait数据的线程。

4.MTask::future:存储了future的信息,用了智能指针,主要是等待线程需要持有一份,处理线程也需要持有一份,2个线程是通过future里面的cond来唤醒

5.MTask::func:存储了lambda函数

6.为I32实现了默认值的接口,方便后面初始化的时候获取默认值。

二.future实现

rust 复制代码
impl <T>MFuture<T> where T:DefaultValue + Copy{
    fn get(&self)-> T {
        loop {
            let mut complete = self.mutex.lock().unwrap();
            if complete.0.eq(&true) {
               return complete.1;
            } else {
                self.cond.wait(complete);
            }
        }
    }
}

原理比较简单,从future中获取数据元,如果元组第一个为true,则表明计算完成,直接返回数据,否则就调用condvar来等待。

三.模拟场景

线程1->list放入各种lambda函数

线程2->从list取出lambda函数,计算后将结果存放到future

线程1:

rust 复制代码
let mut list: Arc<Mutex<Vec<MTask<i32>>>> = Arc::new(Mutex::new(Vec::<MTask<i32>>::new()));//1
    
    let mut closure1 = list.clone();
    thread::spawn(move || {
        let mut count = 0;
        loop {
            thread::sleep(Duration::from_secs(1));

            let ll = || {
                println!("fn start");
                thread::sleep(Duration::from_secs(1));
                println!("fn finish start");
                123
            };//2

            let future = Arc::new(MFuture {
                mutex:Mutex::new((false,i32::getDefault())),
                cond:Condvar::new()
            }); //3

            let task = MTask {
                future:future.clone(),
                func:Box::new(ll)
            };//4

            {
                let mut l = closure1.lock().unwrap();
                l.push(task);
            } //5

            let f1 = future.clone();
            println!("v is {}",f1.get());//6
        }
    });

1.创建一个队列用来存放所有的task,类似一个生产者/消费者模型。

2.创建一个lambda函数,这里简单写了一个直接返回i32的函数,实际场景可能会是比较负责的函数。

3.生成一个future,这里i32::getDefault()获取默认数据,模板玩的不溜,这里直接写死了。照理应该不需要指定i32.

4.将回调函数保存下来,注意,这里是用Box来保存的。

5.将这个task推到队列里面

6.调用get函数 ,如果没有计算完,等待。哈哈。

线程2:

rust 复制代码
let mut closure2 = list.clone();
    thread::spawn(move || {
        loop {
            thread::sleep(Duration::from_millis(500));
            let mut v = closure2.lock().unwrap();
            if v.len() == 0 {
                continue;
            }

            let mut vv = v.pop().unwrap();
            let ret = (vv.func)();//1
            let mut comp = vv.future.mutex.lock().unwrap();
            comp.0 = true;//2
            comp.1 = ret;//2
            vv.future.cond.notify_all();//3
        }
    }).join();

1.调用线程1中保存的lambda函数,执行获取结果

2.更新future中用来保存运算结果的数据元。comp.0表示是否计算完成,comp.1存放运算结果

3.唤醒所有等待线程

接下来运行看一下结果:

相关推荐
QuantumStack7 分钟前
【C++ 真题】P1104 生日
开发语言·c++·算法
whoarethenext23 分钟前
使用 C++/OpenCV 和 MFCC 构建双重认证智能门禁系统
开发语言·c++·opencv·mfcc
天水幼麟29 分钟前
动手学深度学习-学习笔记【二】(基础知识)
笔记·深度学习·学习
沧海一笑-dj1 小时前
【51单片机】51单片机学习笔记-课程简介
笔记·学习·51单片机·江科大·江科大学习笔记·江科大单片机·江科大51单片机
代码的奴隶(艾伦·耶格尔)1 小时前
后端快捷代码
java·开发语言
老虎06271 小时前
JavaWeb(苍穹外卖)--学习笔记04(前端:HTML,CSS,JavaScript)
前端·javascript·css·笔记·学习·html
Jay_5152 小时前
C++多态与虚函数详解:从入门到精通
开发语言·c++
路来了2 小时前
Python小工具之PDF合并
开发语言·windows·python
大苏打seven2 小时前
Docker学习笔记:Docker网络
笔记·学习·docker
xiaolang_8616_wjl2 小时前
c++文字游戏_闯关打怪
开发语言·数据结构·c++·算法·c++20