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

哈哈,主要是为了练习一下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.唤醒等待线程

运行结果:

相关推荐

  1. 一个线

    2024-03-10 16:18:03       18 阅读
  2. 一步一步线之十一线应用内存

    2024-03-10 16:18:03       12 阅读
  3. 完成一个程序,谈谈Rust线并行算法的体会

    2024-03-10 16:18:03       18 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-03-10 16:18:03       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-03-10 16:18:03       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-03-10 16:18:03       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-03-10 16:18:03       20 阅读

热门阅读

  1. pytorch升级打怪(一)

    2024-03-10 16:18:03       22 阅读
  2. 力扣77-组合

    2024-03-10 16:18:03       24 阅读
  3. 设计模式之单例模式

    2024-03-10 16:18:03       22 阅读
  4. IntelliJ IDEA分支svn

    2024-03-10 16:18:03       28 阅读
  5. Linux运维_Bash脚本_编译安装GTK+-3.24.41

    2024-03-10 16:18:03       25 阅读
  6. Windows中毒应急方式

    2024-03-10 16:18:03       19 阅读
  7. c#开发100问?

    2024-03-10 16:18:03       24 阅读
  8. 初识C语言—结构体

    2024-03-10 16:18:03       24 阅读
  9. 教你用Android Studio如何打jar包与aar包

    2024-03-10 16:18:03       20 阅读