线程应用(线程池)

待我称王封你为后i 2023-01-16 12:24 249阅读 0赞

线程池:

创建一堆工作线程(有最大数量限制),以及一个线程安全的队列,这些工作线程不断从任务队列取出任务进行处理

优点:

  1. 避免资源无限制使用所造成的资源耗尽的风险
  2. 避免频繁创建大量线程与销毁所带来的时间成本

实现:

  1. 直接在线程入口函数中定义好各种不同类型的处理方法
  2. 要处理什么数据,以及数据如何处理由外部传入
  3. 核心线程将需要处理的数据以及方法组织成一个任务,抛入线程池
  4. 线程池中的工作线程从任务队列中取出线程方法并处理数据

    • 设计一个任务类(包含数据,以及处理方法,通过run接口,线程池中的线程获取节点后调用该接口就可以处理数据)run为公有接口封装私有成员函数

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM2MTMxNjEx_size_16_color_FFFFFF_t_70

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM2MTMxNjEx_size_16_color_FFFFFF_t_70 1

  • 设计线程池类(线程(构造函数直接创建)+线程安全任务队列)
  • 私有成员变量:最大线程数,最大队列节点数
  • 创建线程入口函数entry,注意 entry作为入口函数参数仅有一个 ,如果在设计线程池类的过程中将其作为成员函数,存在隐含的this指针,导致入口函数的参数并非一个,不满足入口函数的定义
  • 需要将入口函数entry设置为static成员函数,消除其中隐含的this指针,但此时又存在另外一个问题,导致入口函数无法访问私有成员变量(线程安全任务队列),此时在create线程时将this作为参数传入到入口函数中
  • 线程池类定义任务入池操作,将每一个创建的任务节点放入线程池中,即线程池的任务安全队列中
  • 每次调用任务,通过入口函数entry,将任务节点从线程池的队列中出队,然后调用run接口处理数据
  • 在任务安全队列,取任务 放任务的过程需要加锁保护(BlockQueue),在调用run不需要加锁保护,因为取出不同的任务节点,调用不同的run接口,与其他线程不存在竞争

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM2MTMxNjEx_size_16_color_FFFFFF_t_70 2

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM2MTMxNjEx_size_16_color_FFFFFF_t_70 3

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM2MTMxNjEx_size_16_color_FFFFFF_t_70 4

线程安全的单例设计模式:

应用场景:一个类只能实例化一个对象;一份资源只能被加载一次

实现:

  • 饿汉模式:资源在程序初始化阶段就完成加载(空间换时间)
  • 饿汉方法实现:
  1. 采用静态方法修饰资源,所有对象共用同一份资源,程序初始化阶段完成资源加载且只被加载一次
  2. 构造函数私有化 ,保证一个类只能实例化一个对象

    template
    class Singleton {

    1. static T data;
    2. Singleton(){}//构造函数私有化

    public:

    1. static T* GetInstance() {
    2. return &data;
    3. }

    };

    • 懒汉模式:资源在使用的时候再去加载(延迟加载)
  3. 定义对象指针,初始资源为空

  4. static修饰,共用一份资源
  5. volatite修饰 ,防止编译器过度优化
  6. 加锁保护 线程安全
  7. 二次检测,防止锁冲突

    template
    class Singleton {

    1. volatite static T* inst;//定义对象指针 初始为空
    2. static std::mutex _mutex;

    public:

    1. static T* GetInstance() {
    2. if(inst==NULL)//double check 二次检测,避免不为空情况依然加锁,造成锁冲突
    3. {
    4. _mutex.lock();
    5. if (inst == NULL) {
    6. inst = new T();//调用时发现为空,进行获取资源
    7. }
    8. _mutex.unlock();
    9. }
    10. return inst;
    11. }

    };

注:STL容器 线程非安全

智能指针 线程安全

发表评论

表情:
评论列表 (有 0 条评论,249人围观)

还没有评论,来说两句吧...

相关阅读

    相关 线线

    软件大师又要给弟子开小灶了,这次是线程和线程池。 软件大师正在闭目修炼, 最小的一名弟子慢慢走了进来。 大师,最近我在学习线程,有很多迷惑的地方。 说来听听,让