秋招日记(四)线程池实现表达

学习记录

  • 《深入理解计算机系统》
    • 第9章 虚拟内存
    • 第10章 系统I/O
    • 第11章 网络编程
    • 第12章 并发编程

我的面试问题解答

  • 线程池实现的一段话描述

    (PS:我这个线程池的实现是参考(CV)文章后面的github项目,这里的实现描述也是我自己的理解)

    线程池的核心思想就是维护一个线程容器和一个任务容器,我的线程池实现的本质是所有线程共享一个线程安全的任务队列,并在此基础上实现一个简单的生产者消费者模型。

    在我的实现中我创建了一个function<void>类型的队列用来保存需要被执行的任务,让后将这个队列和一个互斥锁、一个条件变量以及一个布尔变量打包成一个结构体,其中互斥锁用来保护任务队列的线程安全、条件变量用来阻塞线程使线程处于空闲状态或通知线程处理任务,布尔变量用来关闭线程。

    然后我使用了一个shared_ptr指针来管理一个任务队列结构体对象

    在创建线程池时,我使用std::thread来动态创建线程。创建线程时,我将持有任务队列的shared_ptr指针传入每个线程中,使得所有线程都能拥有工作队列的所有权

    每个线程的主体都是一个无限循环,循环中通过判断shared_ptr指向的任务队列是否为空,来确定是否需要执行任务,当任务队列为空时,线程会被任务队列结构体中的条件变量阻塞,当任务列表不为空时,线程取出任务并执行。

  • 线程池实现

    • 线程池是什么?
      • 线程池是一组预实例化的空闲线程,它们随时可以被分配工作。
      • 当需要完成大量短任务而不是少量长任务时,它们比为每个任务实例化新线程更可取。这可以避免多次创建线程的开销。
    • 实现一个线程池的要求
      • 一种创建线程并将它们保持在空闲状态的方法。
      • 存储已创建线程的容器,如队列或任何其他能够将线程添加到池中并取出一个线程的结构。
      • 保存需要处理的任务的容器
      • 线程工作时使用的标准接口或抽象类。
    • 线程池的工作流程
      • 创建一组线程,并将创建的线程放入线程池中
      • 当线程池被传递一个Task时,它从容器中获取一个线程(或者在容器为空时等待一个可用的线程),传递给它一个Task
      • 一旦执行完成,线程将自己交还给池,将其放入容器中以供重用,然后阻塞自身,使自己处于睡眠状态,直到循环重复。
    • 线程池的具体实现
      • 线程池的成员
        • 一个线程池结构体
          • 一个互斥锁 std::mutex, 用来保护工作队列的线程安全
          • 一个条件变量 std::condition_variable,阻塞线程让线程保持在空闲状态
          • 一个布尔变量 bool isClosed,用来关闭线程
          • 一个function类型的队列 std::queue<std::function<void()>>,用来存放等待执行的任务
        • 一个持有线程池结构体对象的shared_ptr
      • 线程池的初始化
        • 使用std::thread循环创建线程,创建后及时分离线程(detach)
        • 线程内部是一个无限循环,当没有任务需要处理时,线程被条件变量阻塞
        • 每个线程都持有线程池结构体对象的shared_ptr指针,通过该指针,线程可以从任务队列中取出任务并执行
      • 线程池的析构
        • 将线程池结构体中的布尔变量值置为false,并使用条件变量通知所有线程,线程被唤醒后退出无限循环
      • 任务的存放与取出
        • 使用std::forward将任务完美转移到工作队列中
        • 使用条件变量通知一个线程处理

参考

图片(线程池wiki图片),在想到线程池的时候,脑子里最好有这个印象



#我的秋招日记##面试题目#
全部评论
线程池有时候很有用的
点赞 回复 分享
发布于 2022-07-26 11:47
可以试一试荣耀。荣耀2023届校园招聘现已正式启动,内推码:yuhvad 网址https://career.hihonor.com/SU60eea919bef57c1023f6fe78/pb/school.html
点赞 回复 分享
发布于 2022-07-27 09:41

相关推荐

评论
5
19
分享

创作者周榜

更多
牛客网
牛客企业服务