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


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

    一.Executor申明

    1. struct AExecutor {
    2. results:Arcu32,T>>>, //1
    3. functions:ArcVec>>> //2
    4. }

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

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

    二.Task申明

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

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

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

    3.id:future对应的id

    三.Future申明

    1. struct AFuture {
    2. id:u32, //1
    3. map:Arcu32,T>>>,//2
    4. cond:Arc//3
    5. }

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

    2.map:存放结果的map

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

    四.Future实现

    1. impl AFuture {
    2. fn get(&self)-> T {
    3. loop {
    4. let mut map = self.map.lock().unwrap();
    5. let value = map.remove(&self.id);
    6. match value {
    7. Some(v) => {return v;}
    8. None=> {
    9. self.cond.wait(map);
    10. }
    11. }
    12. }
    13. }
    14. }

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

    五.Executor提交任务

    1. fn submit(&self,func:Box<dyn Fn()-> T + 'static + Send>)->AFuture {
    2. let cond = Arc::new(Condvar::new()); //1
    3. let id:u32 = 1;
    4. let task = ATask{
    5. func:func,
    6. cond:cond.clone(),
    7. id:id.clone()
    8. };
    9. {
    10. let mut ll = self.functions.lock().unwrap();
    11. ll.push(task); //2
    12. }
    13. AFuture {
    14. id:id.clone(),
    15. map:self.results.clone(),
    16. cond:cond.clone(),
    17. }//3
    18. }

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

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

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

    六:Executor执行任务

    1. fn work(&self) {
    2. loop {
    3. println!("work start");
    4. thread::sleep(Duration::from_secs(10)); //1
    5. let mut ll: std::sync::MutexGuard<'_, Vec>> = self.functions.lock().unwrap();
    6. println!("len is {}",ll.len());
    7. if ll.len() == 0 {
    8. continue;
    9. }
    10. let task = ll.pop().unwrap(); //2
    11. drop(ll);//3
    12. let result = (task.func)();
    13. {
    14. let mut results = self.results.lock().unwrap();
    15. results.insert(task.id,result);//4
    16. }
    17. task.cond.notify_all();//5
    18. }
    19. }

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

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

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

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

    5.唤醒等待线程

    运行结果:

  • 相关阅读:
    git and svn 行尾风格配置强制为lf
    【数据结构】算法的时间复杂度和空间复杂度
    数据结构与算法-生成树与最小生成树
    Jenkins自动构建(Gitee)
    专业运动耳机哪个牌子好、专业运动耳机推荐
    Ubuntu 安装Kafka
    盘点常见的动态内存的错误
    勒索病毒横行下设备该如何进行加密防护
    阻止网络钓鱼诈骗的技巧
    【申报指南】国家高新技术企业的认定标准、认定条件及奖励政策
  • 原文地址:https://blog.csdn.net/wang_sun_1983/article/details/136525791