rust学习(手动写一个线程池)

news/2024/7/23 11:09:41 标签: rust, 学习, 开发语言

哈哈,主要是为了练习一下rust的语法,不喜勿喷。

一.Executor申明

rust">struct AExecutor<T> {
    results:Arc<Mutex<HashMap<u32,T>>>, //1
    functions:Arc<Mutex<Vec<ATask<T>>>> //2
}

1.results:用来存放结果,其中u32是一个future的id,T表示存放的数据

2.functions: 存放所有submit的任务

二.Task申明

rust">struct ATask<T> {
    func:Box<dyn Fn()-> T + 'static + Send>, //1
    cond:Arc<Condvar>,//2
    id:u32//3
}

1.func:任务对应的lambda函数

2.cond:用来唤醒客户端(调用future.get等待结果的客户端)

3.id:future对应的id

三.Future申明

rust">struct AFuture<T> {
    id:u32, //1
    map:Arc<Mutex<HashMap<u32,T>>>,//2
    cond:Arc<Condvar>//3
}

1.id:这个future的id,通过这个id可以在map中找到结果

2.map:存放结果的map

3.cond:用来等待计算完成的condition,和Task结构体中的cond是同一个,这样task完成后就能唤醒等待了。

四.Future实现

rust">impl <T>AFuture<T> {
    fn get(&self)-> T {
        loop {
            let mut map = self.map.lock().unwrap();
            let value = map.remove(&self.id);
            match value {
                Some(v) => {return v;}
                None=> {
                    self.cond.wait(map);
                }
            }
        }
    }
}

只有一个get函数,如果有数据,就返回该数据,否则就等待唤醒

五.Executor提交任务

rust">fn submit(&self,func:Box<dyn Fn()-> T + 'static + Send>)->AFuture<T> {
        let cond = Arc::new(Condvar::new()); //1
        let id:u32 = 1;
        let task = ATask{
            func:func,
            cond:cond.clone(),
            id:id.clone()
        };

        {
            let mut ll = self.functions.lock().unwrap();
            ll.push(task); //2
        }

        AFuture {
            id:id.clone(),
            map:self.results.clone(),
            cond:cond.clone(),
        }//3
    }

1.创建一个Condition,用智能指针控制,这样计算和等待的线程都能使用。这个Condition会同时存放到task/future中。

2.将task存放到任务队列,计算线程就是从这个队列中获取任务的。

3.返回future,cond就是步骤1创建的cond

六:Executor执行任务

rust">fn work(&self) {
        loop {
            println!("work start");
            thread::sleep(Duration::from_secs(10)); //1
            let mut ll: std::sync::MutexGuard<'_, Vec<ATask<T>>> = self.functions.lock().unwrap();
            println!("len is {}",ll.len());
            if ll.len() == 0 {
                continue;
            }
            
            let task = ll.pop().unwrap(); //2
            drop(ll);//3

            let result = (task.func)();
            {
                let mut results = self.results.lock().unwrap();
                results.insert(task.id,result);//4
            }
            task.cond.notify_all();//5
        }
    }

1.这里用来管理任务的队列没有做成blocking的,所以暂时用一个sleep代替

2.从任务队列里面取出task

3.释放ll(lockguard),这样锁就释放了

4.将结果存放到结果的表里

5.唤醒等待线程

运行结果:


http://www.niftyadmin.cn/n/5417144.html

相关文章

【vue2基础教程】vue指令

文章目录 前言一、内容渲染指令1.1 v-text1.2 v-html1.3 v-show1.4 v-if1.5 v-else 与 v-else-if 二、事件绑定指令三、属性绑定指令总结 前言 Vue.js 是一款流行的 JavaScript 框架&#xff0c;广泛应用于构建交互性强、响应速度快的现代 Web 应用程序。Vue 指令是 Vue.js 中…

scrapy分布式爬虫的部署,调度,与管理(scrapy + scrapy-redis + scrapyd + gerapy)

使用到的框架及软件包介绍 Github Gerapy 提供主机管理,爬虫项目管理,爬虫任务管理的web管理后台。Github Scrapy-redis 提供中心化的任务队列,任务指纹队列,供分布式爬虫共享爬取任务队列。Github Scrapyd 提供通过api方式单机部署爬虫的功能,爬虫状态查询等。Github Scr…

突破编程_C++_设计模式(桥接模式)

1 桥接模式的基本概念 桥接模式&#xff08;Bridge Pattern&#xff09;是一种结构型设计模式&#xff0c;它的基本概念是将抽象部分与它的实现部分分离&#xff0c;使它们都可以独立地变化。在桥接模式中&#xff0c;抽象部分和实现部分被放在两个不同的类层次中&#xff0c;…

流浪猫流浪狗领养源码

流浪猫流浪狗领养源码 适合做猫狗宠物类的发信息发布。当然其他信息发布也是可以的。刚刚开发出炉的&#xff01; 源码截图&#xff1a; 免费下载地址&#xff1a;https://download.csdn.net/download/u012241616/88935678

ELK日志中心搭建(六)- harbor镜像仓库

CentOS 搭建 Harbor 镜像仓库&#xff08;图文详解&#xff09;_centos harbor-CSDN博客

力扣大厂热门面试算法题 9-11

9. 回文数&#xff0c;10. 正则表达式匹配&#xff0c;11. 盛最多水的容器&#xff0c;每题做详细思路梳理&#xff0c;配套Python&Java双语代码&#xff0c; 2024.03.08 可通过leetcode所有测试用例。 目录 9. 回文数 解题思路 完整代码 Java Python 10. 正则表达式…

Python 一步一步教你用pyglet仿制鸿蒙系统里的时钟

目录 鸿蒙时钟 1. 绘制圆盘 2. 创建表类 3. 绘制刻度 4. 刻度数值 5. 添加指针 6. 转动指针 7. 联动时间 8. 时钟走动 鸿蒙时钟 本篇将用python pyglet库复刻华为手机鸿蒙系统闹钟程序的时钟&#xff0c;先在上图中抓取出时分秒针及刻度、表盘的颜色RGB值&#xff1a…

漫谈技术成长

引言 相信很多程序员在自己的技术成长之路上&#xff0c;总会遇到许许多多的难关&#xff0c;有些难关咬咬牙就过去了&#xff0c;而有点难关则需要有一定的能力&#xff0c;才能克服。因此&#xff0c;本文主要围绕“技术成长” 话题&#xff0c;为何会选择技术方向&#xff0…