首页 > 编程语言 >C++11手写线程池1

C++11手写线程池1

时间:2023-10-16 22:33:07浏览次数:44  
标签:11 调用 函数 队列 阻塞 C++ 任务 线程

  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是一个注射

标签:11,调用,函数,队列,阻塞,C++,任务,线程
From: https://www.cnblogs.com/lvshy/p/17768556.html

相关文章

  • CF1168C And Reachability
    CF1168CAndReachabilityAndReachability-洛谷|计算机科学教育新生态(luogu.com.cn)目录CF1168CAndReachability题目大意思路code题目大意给定一个长度为\(n\)的数组\(a\)。你可以选择一个长度为\(k\)的数组\(p\)\(p_1=x,p_k=y\)当\(x<y\)且\(a_......
  • CF1168C
    CF1168C题面及数据范围Ps:链接为洛谷OJ。发现对于每一个\(i\)需要求经过若干次转移使第\(j\)个二进制位为\(1\)的最近位置\(k\),查询时,当\(k\leqy\)便可以到达。下文的位无特殊说明位均指二进制位。设\(f[i][j]\)为\(i\)经过转移使第\(j\)位为\(1\)的最近点......
  • C++接入redis
    项目地址https://github.com/sewenew/redis-plus-plushttps://github.com/redis/hiredis#1、编译安装hiredis项目wgethttps://github.com/redis/hiredis/archive/refs/tags/v1.2.0.tar.gzcdhiredis#编译安装make&&makePREFIX=安装到指定目录install#2、编译......
  • C++的简单语法
    ​C++库里面的一些基础函数以及迭代器的使用:迭代器:首先,可以将迭代器简单地从方向和限制简单地分为四类:1.正向   intmain(){ strings1="hello"; s1+=""; s1+="world"; cout<<s1<<endl; string::iteratorit1=s1.begin();//在这里,s1.begin()代表......
  • CF1119F Niyaz and Small Degrees 题解
    原题翻译首先\(O(n^2\logn)\)的dp是simple的,我们设\(dp_{i,0/1}\)表示以\(i\)为根,\(i\)到\(fa_i\)这条边删/不删的最小权值和。转移是一个非常trick的问题,只需要假设所有都选\(dp_{i,0}\),然后把所有儿子按照\(dp_{v,1}+w(u,v)-dp_{v,0}\)排序,选前\(d......
  • java实现大文件多线程上传案例
    当机器内存大小为4G,需要上传一个大小为50G的文件时,为了避免内存溢出,可以采用分片上传的方式,即将大文件切分成多个小片段进行并发上传。以下是一个详细的方案和代码实现示例:方案说明:将大文件切分成多个大小适当的片段(例如每个片段大小为100MB)。创建一个线程池来管理并发上传任务,......
  • 16核22线程!酷睿Ultra 9 185H曝光:英特尔革命性架构转变
    在近日的英特尔ON技术创新峰会上,英特尔公布了代号为MeteorLake的第一代酷睿Ultra处理器的最新消息。据英特尔介绍,该处理器将于今年12月14日正式上市,预计搭载酷睿Ultra移动处理器的首批笔记本将在今年底首发,并且在春节前后大量出货。和经典的i3、i5、i7以及i9定位类似,第一代酷......
  • 文心一言 VS 讯飞星火 VS chatgpt (114)-- 算法导论10.2 7题
    七、用go语言,给出一个O(n)时间的非递归过程,实现对一个含n个元素的单链表的逆转。要求除存储链表本身所需的空间外,该过程只能使用固定大小的存储空间。文心一言:在Go语言中,你可以使用迭代方法来反转一个单链表。这种方法只需要O(1)的额外空间。首先,我们需要定义链表的数据结构:t......
  • 文心一言 VS 讯飞星火 VS chatgpt (114)-- 算法导论10.2 7题
    七、用go语言,给出一个O(n)时间的非递归过程,实现对一个含n个元素的单链表的逆转。要求除存储链表本身所需的空间外,该过程只能使用固定大小的存储空间。文心一言:在Go语言中,你可以使用迭代方法来反转一个单链表。这种方法只需要O(1)的额外空间。首先,我们需要定义链表的数据结构:type......
  • linux c++程序使用MD5
    为避免找到的开源md5算法有坑,一般直接用openssl自带的MD5相关函数实现;一般系统已默认安装openssl,没装的话直接指令安装ubuntusudoapt-getinstalllibssl-devcentossudodnfinstallopenssl-devel示例代码#include<openssl/md5.h>unsignedcharmd5[MD5_DIGEST_LENGT......