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

news2025/2/21 19:34:12

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

一.Executor申明

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申明

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申明

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实现

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提交任务

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执行任务

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.coloradmin.cn/o/1514108.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

docker-compose up -d使用遇到问题no configuration file provided: not found

docker-compose up -d使用遇到问题&#xff0c;因为你文件名称没指定&#xff0c; 又找不到默认的文件名称&#xff1b;如果该目录下有个文件叫docker-compose.yml时&#xff0c;那么可以直接使用docker-compose up -d;否则就要使用docker-compose -f mysql up -d

IP数据报格式

每一行都由32位比特&#xff0c;即4个字节组成&#xff0c;每个格子称为字段或者域。IP数据报由20字节的固定部分和最大40字节的可变部分组成。 总长度 总长度为16个比特&#xff0c;该字段的取值以字节为单位&#xff0c;用来表示IPv4数据报的长度(首部长度数据载荷长度)最大…

【阿里云系列】-基于云效构建部署Springboot项目到ACK

介绍 为了提高项目迭代的速度加速交付产品给客户&#xff0c;我们通常会选择CICD工具来减少人力投入产生的成本&#xff0c;开源的工具比如有成熟的Jenkins&#xff0c;但是本文讲的是阿里云提高的解决方案云效平台&#xff0c;通过配置流水线的形式实现项目的快速部署到服务器…

(第73天)DBUA 升级:单机 11GR2 升级到 19C

前言 Oracle 11GR2 版本是上一个长期稳定版本,但是官方已与 2020 年停止服务,官方建议升级到最新长期稳定版 19C。 参考官方文档:当前数据库版本的发行时间表 (Doc ID 1626244.1) Database Upgrade Assistant (DBUA) 交互式的引导我们完成升级数据库的步骤,它会自动执行为…

前端去除网页水印

按F12&#xff0c;打开开发者工具面板&#xff0c;然后直接在样式搜索backgroud 然后直接取消backgroud 的复选框即可。

每天五分钟计算机视觉:图像数据不足带来的问题和解决办法

本文重点 在当今的数字时代,图像数据的应用已经渗透到各个领域,包括但不限于计算机视觉、机器学习、自动驾驶、医疗诊断等。然而,当图像数据不足时,会引发一系列问题,对相关应用产生负面影响。 尤其是计算机视觉领域,图像数据尤为珍贵和稀缺,如果计算机视觉的任务中,如…

Linux本地搭建FastDFS系统

文章目录 前言1. 本地搭建FastDFS文件系统1.1 环境安装1.2 安装libfastcommon1.3 安装FastDFS1.4 配置Tracker1.5 配置Storage1.6 测试上传下载1.7 与Nginx整合1.8 安装Nginx1.9 配置Nginx 2. 局域网测试访问FastDFS3. 安装cpolar内网穿透4. 配置公网访问地址5. 固定公网地址5.…

Git版本工具学习

目录 版本控制git配置工作区域文件状态git对象模型基础命令.gitignore忽略文件IDEA集成Git 版本控制 本地版本控制&#xff1a;在本地记录每一次版本更新。 集中版本控制&#xff1a;版本数据都保存在单一服务器&#xff0c;不联网就看不到版本信息。SVN 分布式版本控制&…

漏洞发现-漏扫项目篇武装BURP浏览器插件信息收集分析辅助

知识点 1、插件类-武装BurpSuite-漏洞检测&分析辅助 2、插件类-武装谷歌浏览器-信息收集&情报辅助 章节点&#xff1a; 漏洞发现-Web&框架组件&中间件&APP&小程序&系统 扫描项目-综合漏扫&特征漏扫&被动漏扫&联动漏扫 Poc开发-Ymal语…

吴恩达机器学习-可选的实验室-正则化成本和梯度(Regularized Cost and Gradient)

文章目录 目标添加正则化正则化代价函数正则化梯度下降重新运行过拟合示例恭喜 目标 在本实验中&#xff0c;你将: 用正则化项扩展前面的线性和逻辑代价函数。重新运行前面添加正则化项的过拟合示例。 import numpy as np %matplotlib widget import matplotlib.pyplot as p…

Xterminal:未来的终端体验

✅作者简介&#xff1a;大家好&#xff0c;我是Leo&#xff0c;热爱Java后端开发者&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;Leo的博客 &#x1f49e;当前专栏&#xff1a; 开发环境篇 ✨特色专栏&#xff1a; M…

关于类和对象超级初级小白知识

下面的内容只是一小部分&#xff0c;在整个面向对象的知识中并不完整&#xff0c;用于记忆和梳理 目录 前言&#xff1a;类和对象是什么&#xff1f; 一、定义类 1.如何定义类 2.类的注意事项 二.类的实例化 1.创建对象的基础知识 2.如何创建对象 3.实例化举例 4.访问对象…

软考75-上午题-【面向对象技术3-设计模式】-设计模式的要素

一、题型概括 上午、下午题&#xff08;试题五、试题六&#xff0c;二选一&#xff09; 每一个设计模式都有一个对应的类图。 二、23种设计模式 创建型设计模式&#xff1a;5 结构型设计模式&#xff1a;7 行为设计模式&#xff1a;11 考试考1-2种。 三、设计模式的要素 3…

数据驱动下的私域运营战略布局

一、以用户为中心的组织重构或整合 发现&#xff0c;市场上大部分做的非常成功的私域项目&#xff0c;都是由CEO推动的、基于该战略的组织重构去驱动的。 我们也看到&#xff0c;在很多公司&#xff0c;私域运营是由品牌部门、CRM部门和Trade Marketing部门合作一起运营的。 …

FineReport报表如何在单元格中显示本地图片(图片地址已存储到MySQL数据库中)

帆软帮助文档对应查看链接&#xff1a;https://help.fanruan.com/finereport/doc-view-854.html?source4#需求&#xff1a;在设计FineReport报表时&#xff0c;想在单元格中显示图书信息对应的图片&#xff0c;图片路径已存储到MySQL数据库中 一、查询数据库 查询MySQL中图书…

一起玩儿3D打印机——02 3D打印机TinyBee主板、Marlin固件

摘要&#xff1a;本文介绍3D打印主板、固件 在前边已经介绍了3D打印机的基本组成&#xff0c;其中主板是3D打印机的硬件核心&#xff0c;而固件则是3D打印机的软件核心&#xff0c;在进行选择的两者一定要配合起来。因为3D打印机的核心处理器&#xff0c;不像PC机这样&#xff…

计算机网络-第4章 网络层(2)

主要内容&#xff1a;网络层提供的两种服务&#xff1a;虚电路和数据报&#xff08;前者不用&#xff09;、ip协议、网际控制报文协议ICMP、路由选择协议&#xff08;内部网关和外部网关&#xff09;、IPv6,IP多播&#xff0c;虚拟专用网、网络地址转换NAT&#xff0c;多协议标…

零基础自学C语言|自定义类型:联合与枚举

✈联合体 &#x1f680;联合体的类型声明 像结构体一样&#xff0c;联合体也是由一个或者多个成员构成&#xff0c;这些成员可以不同的类型。 但是编译器只为最大的成员分配足够的内存空间。联合体的特点是所有成员共用同一块内存空间。所以联合体也叫&#xff1a;共用体。 给…

鸿蒙开发月薪过万,背后的秘密~

自从智联招聘公布出春节后首周的岗位需求数据后&#xff0c;鸿蒙开发岗位就被推上了热潮&#xff01;鸿蒙相关职位数同比增长163%&#xff0c;投递人数同比增长349%&#xff0c;即分别增至去年同期的2.6倍、4.5倍&#xff0c;涨势突出。 于是我的朋友圈中就有人去市场中简单探…

Linux下menuconfig与Kconfig基础知识概要

一、简介 menuconfig是Linux平台用于管理代码工程、模块及功能的实用工具。上至决定某一程序模块是否编译&#xff0c;下到某一行具体的代码是否需要编译以及某个项的值在本次编译时该是什么都可由menuconfig来定义。 menuconfig的使用方式通常是在编译系统之前在系统源代码根…