C++11手写线程池1

发布时间 2023-10-16 22:30:45作者: SunShine789
  1. 线程池结构  
    1.   任务队列结构体  保存一个回调函数指针和一个,参数指针

       实现任务队列

       为了多个生产者 多个消费者取东西混乱的避免要加互斥锁

    2. 线程池threadpool类 要实现的
      1.   初始化一个线城池 参数是最小数和最大数  

         malloc和new的区别 new要调用该类的构造函数 而mall哦草不用 直接在内存中创建  失败就抛异常new 还可以进行初始化

         是否关闭线程池 默认是FALSE  如果构造失败要释放资源的  memser初始化内存 三个参数  变量名+0+多个

      2. 销毁线程池 析构
      3. 加入一个任务
      4. 获取忙碌线程
      5. 获取空闲线程
      6. 管理线程
      7. 私有属性

      8. 任务具体函数

  2. 为了保护pthread线程  要求回调函数必须是有效地址   类内静态函数或普通外部函数  因为静态函数就像外部函数一样有自己的对地址,而内部函数只有类对象创建时才有

  3. 当这个静态函数想访问类内非静态成员时,要用this指针去访问,this指针本身又是void* 类型,完美符合,同时立马在函数内做类型转换

     这个static——cast相当于C语言里的强制类型转换

  4. 静态类对内部函数和变量的一系列操作都需要this指针  这个pool就是this

     条件阻塞 判断是不是需要销毁线程

  5. 工作函数其实就是不断的由线程池里的线程不断地取任务
    1.   首先就是先给整个线程池加上一把锁
    2. 判断这个任务队列是不是空的并且这个线程池没有被关闭  就把工作线程阻塞在notempty上,也就是说notempty记录了哪些工作线程被阻塞了,同时整个线程池的锁mutexpool也被解开了
    3. 当生产者线程开始唤醒阻塞工作线程后,线程又重新拿到了这个锁,继续向下执行
    4. 管理者线程判断是不是要销毁线程
    5. 从任务队列中取出一个任务,马上要开始工作了,busynumber++
    6. 解锁 任务队列 线程池
    7. 调用取出来的任务函数 任务执行完之前 该线程一直阻塞在这,后面就把这个GIA释放那个的资源释放
    8. 做日志输出
    9. 工作完线程busynumber-- 由于这个应该互斥访问所以加一把锁
  6. 线程退出

     将线程ID修改为0就可以了 nullptr

  7. 管理者线程所要掌管的操作
    1.   如果当前线程不够用 同时又小于最大线程数 那就创建线程,显然这个操作要加锁 
    2. 创建线程ID在数组里面找一个,定义回调函数为worker 现存活数+1
    3. 随后解锁

    4. 如果当前忙的线程*2 小于存活线程数 并且存活的大于最小线程数  忙线程应该包括在存活里 因为线程存在也会消耗系统资源,所以必要消毁

       这时候逻辑很巧妙! 就去唤醒阻塞在条件里的工作线程,在那里它将迎来生命的终结

  8. 线程池添加任务函数函数  直接调用task对象的push操作就可以了

     不需要再加互斥锁了,因为已经

     在内部锁住了

  9. 获取忙碌和存活线程数 有可能修改

  10. 线程池整个全部析构掉的全部工作
    1.   阻塞管理者线程
    2. 唤醒所有工作线程
    3. 释放所有对内存 也就是任务队列 线程ID数组

    4. 释放所有的锁 包括大锁和条件变量

  11. Linux下 不会像Windows自动编译动态库,而是要在链接器里的依赖项中添加

     

  12. CTRLH 全局搜索替换

     

  13. 如何在项目中使用线程池

     

  14. 回调函数的典型应用 
    1.   Linux中的信号捕捉 Windows没有信号
    2. 假设我们要捕捉Linux中的某个信号,我们就把这个信号和这个信号的处理函数放到signal里 告诉捕捉了信号,你就做什么,调用的时机由signal控制 不是立即调用
    3. pthread类 注册事物函数 和他们的参数虽然都是void*  不是说这个事物函数去接着调用线程,而是当这个子线程被创建的时候,事物处理的时机也就来了,任务函数调用时机也就成熟了

       

    4. 所以你就能知道epoll是基于回调函数的,因为事件epollwait被触发了,事件就会被处理
    5. C++11新特性 绑定器和function  将一个函数包装成可调用对象

       函数指针使用起来不方便,因为函数指针拿出来后函数还执行不了,需要额外添加实参对象,这时候包装成可调用对象就方便多了

    6. Qt是一个注射