• 手写线程池,能进行任务窃取的线程池---注释


    目录

    function_wrapper.hpp:

    stealing_queue.hpp

    thread_pool_steal.hpp


     

    参考:《C++并发编程实战》

    对于thread_pool_steal.hpp的代码有改动,不然运行不了,详细代码和测试代码参考下一篇文章。

    function_wrapper.hpp:

    //包装可调用对象,对外消除对象型别,还需要有一个函数调用符
    //
    //
    //私有成员:
    //      1.一个虚基类(没有的话在3很难定义一个指向实例化类的指针)
    //      struct impl_base{
    //              1.一个纯虚函数用来让派生类继承3执行函数
    //              2.虚析构函数
    //      }
    //      2.因为需要接受任意类型的可调用对象,所以内部需要封装一个模板类(派生自1>)
    //      template
    //      struct impl_type{
    //              1.成员变量:传入的函数
    //              2.构造函数:移动构造成员变量
    //              3.成员函数:执行函数
    //      }
    //      3.一个指向实例化后的指针(在这里看出确实需要一个基类,可以通过基类指针构
    造派生类指针)
    //公有成员:
    //      1.构造函数,因为接收的对象是任意类型,所以是模板构造函数,并且使用万能引
    用和完美转发实例化私有成员的3.
    //      2.()运算符的重载通过调用私有成员2.的3.实现
    //      3.默认构造函数 = default
    //      4.移动拷贝构造函数
    //      5.移动复制构造函数
    //   

    1. //函数包装器
    2. //包装可调用对象,对外消除对象型别,还需要有一个函数调用符
    3. //
    4. //
    5. //私有成员:
    6. // 1.一个虚基类(没有的话在3很难定义一个指向实例化类的指针)
    7. // struct impl_base{
    8. // 1.一个纯虚函数用来让派生类继承3执行函数
    9. // 2.虚析构函数
    10. // }
    11. // 2.因为需要接受任意类型的可调用对象,所以内部需要封装一个模板类(派生自1)
    12. // template<typename F>
    13. // struct impl_type{
    14. // 1.成员变量:传入的函数
    15. // 2.构造函数:移动构造成员变量
    16. // 3.成员函数:执行函数
    17. // }
    18. // 3.一个指向实例化后的指针(在这里看出确实需要一个基类,可以通过基类指针构造派生类指针)
    19. //公有成员:
    20. // 1.构造函数,因为接收的对象是任意类型,所以是模板构造函数,并且使用万能引用和完美转发实例化私有成员的3.
    21. // 2.()运算符的重载通过调用私有成员2.的3.实现
    22. // 3.默认构造函数 = default
    23. // 4.移动拷贝构造函数
    24. // 5.移动复制构造函数
    25. //

    stealing_queue.hpp
     

    //可以进行任务窃取的队列
    //
    //私有成员:
    //      1.一个双端队列,pop操作在队头进行,steal操作在队尾进行,存储的内容为function_wrapper类
    //      2.互斥 保证安全,因为不存储线程,所以不需要条件变量传递线程运行信息
    //公有成员:
    //      1.默认构造函数
    //      2.push
    //      3.try_pop
    //      4.try_steal基本和pop都一样,就是弹出队尾元素//在线程池中定义一个存储窃取
    队列的vector,vector的索引代表每个线程的标识,这样每个线程就可以通过这个vector访>问窃取队列。
    //      5.empty

    1. //可以进行任务窃取的队列
    2. //
    3. //私有成员:
    4. // 1.一个双端队列,pop操作在队头进行,steal操作在队尾进行,存储的内容为function_wrapper类
    5. // 2.互斥 保证安全,因为不存储线程,所以不需要条件变量传递线程运行信息
    6. //公有成员:
    7. // 1.默认构造函数
    8. // 2.push
    9. // 3.try_pop
    10. // 4.try_steal基本和pop都一样,就是弹出队尾元素//在线程池中定义一个存储窃取队列的vector,vector的索引代表每个线程的标识,这样每个线程就可以通过这个vector访问窃取队列。
    11. // 5.empty

    thread_pool_steal.hpp

    //私有成员:
    //      1.控制线程正常运行的原子变量,抛出异常设置为true
    //      2.线程池的池队列,基于普通的线程安全队列
    //      3.提供索引的队列存储指向窃取队列的指针
    //      4.存放线程的队列
    //      5.封装可联结线程
    //      6.静态本地线程变量 本地线程队列
    //      7.静态本地线程变量 索引
    //
    //      8.work_thread工作函数(任务函数)
    //      9.判断能否从 本地线程队列获取任务
    //      10.判断能否从 线程池队列获取任务
    //      11.判断能否从 其他线程窃取任务
    //公有成员:
    //      1.构造函数:初始化原子变量,可联结线程类。
    //      {
    //              try
    //              {       
    //                      for()
    //                      {初始化提供索引的队列   }
    //                      for()
    //                      {初始化线程}
    //              }
    //              catch
    //      }
    //      2.提交任务函数//为了获取返回值应该返回future,传入各种函数,所以应该是模
    板函数{
    //              1.传入函数打包给pakage_task
    //              2.获取future
    //              3.判断是传入本地线程队列还是线程池队列
    //              4.return future;
    //      }
    //      3.run_package_task//work_thread的主要部分
    //      {
    //              if(判断从哪个队列获得任务)
    //              {
    //                      task()
    //              }
    //              else 交出cpu时间。
    //        }

    //        4.析构函数

    1. //私有成员:
    2. // 1.控制线程正常运行的原子变量,抛出异常设置为true
    3. // 2.线程池的池队列,基于普通的线程安全队列
    4. // 3.提供索引的队列存储指向窃取队列的指针
    5. // 4.存放线程的队列
    6. // 5.封装可联结线程
    7. // 6.静态本地线程变量 本地线程队列
    8. // 7.静态本地线程变量 索引
    9. //
    10. // 8.work_thread工作函数(任务函数)
    11. // 9.判断能否从 本地线程队列获取任务
    12. // 10.判断能否从 线程池队列获取任务
    13. // 11.判断能否从 其他线程窃取任务
    14. //公有成员:
    15. // 1.构造函数:初始化原子变量,可联结线程类。
    16. // {
    17. // try
    18. // {
    19. // for()
    20. // {初始化提供索引的队列
    21. // }
    22. // for()
    23. // {初始化线程}
    24. // }
    25. // catch
    26. // }
    27. // 2.提交任务函数//为了获取返回值应该返回future,传入各种函数,所以应该是模板函数{
    28. // 1.传入函数打包给pakage_task
    29. // 2.获取future
    30. // 3.判断是传入本地线程队列还是线程池队列
    31. // 4.return future;
    32. // }
    33. // 3.run_package_task//work_thread的主要部分
    34. // {
    35. // if(判断从哪个队列获得任务)
    36. // {
    37. // task()
    38. // }
    39. // else 交出cpu时间。
    40. //
    41. // }
    42. //

  • 相关阅读:
    C#中接口的显式实现与隐式实现及其相关应用案例
    C++ 单例模式的各种坑及最佳实践
    压缩包已知密码却跳过密码界面直接弹出解压
    后台交互-首页->与后台数据进行交互,wsx的使用
    Kubernetes云原生实战03 搭建高可用负载均衡器(Keepalived 和 HAproxy)
    虚拟机的网络模式
    推荐几款比较使用的idea插件
    ChatGPT AIGC 实现Excel 交叉查找 Index+match 函数
    Typora导出Word
    Jmeter(三十一):制造大批量的用户数据数据
  • 原文地址:https://blog.csdn.net/qq_52758467/article/details/133686256