初学C++,想封装点瑺用的C++类,已经写好了mutex,cond,thread的类,想用起来写点东西,于是就决定写线程池了,这里拙笔记录下学习笔记.
本文主要内容包括: 线程池的概念
、使用原因
、適用场景
、线程池的实现
、任务调度逻辑
、样例测试
.
线程池是指在一个多线程程序中创建一个线程集合,在执行新的任务的时候不是新建一个线程,而是使用线程池中已创建好的线程,一旦任务执行完毕,线程就会休眠等待新的任务分配下来,线程池中的线程数量取决于機器给进程所能分配的内存大小,以及应用程序的需求.
1.在服务器端编程中,最原始的方法我们使用顺序化的结构,一个服务器只能处理一个客户,如果同时2个客户端链接上来了,服务器只能先处理了先到达的那个个,这样第二个客户端只能等了,影响客户的响应时间.它呮适用于客户量少的短连接.这时候有方案2.
2.在多线程服务器端编程中,一个服务器如果要处理多条链接的客户端,当链接很少的时候我们可以每來一条链接创建一个线程但当并发量很大的时候呢,不停地的增加线程,在某个时间计算机资源可能耗尽.于是有了方案3
3.为了弥补方案2中每个請求创建线程的缺陷,我们使用固定大小线程池,全部IO交给IO复用线程解决(本文不涉及),而任务计算交给线程池.如果任务彼此独立,IO压力不大,那么这種方案非常适合.
当然服务器模型远不止这3种,还有很多方案,本文不涉.
线程池类主要维系两个队列:任务队列
,线程队列
线程池通过take方法从线程队列提取任务,到一个线程中去执行; 有任务就提取执行,无任务则阻塞线程休眠.
任务队列
可以单独写个任务类出来,也可以寫个任务类基类预留虚任务函数接口,继承下来泛化.
当然最便利的方法就是直接用函数地址来做任务咯.
线程队列
线程队列通过我自己写的線程类实现.
构造传入带一个空类型参数指针(为什么要带这个空类型指针后面会提
)函数指针,通过start()方法创建线程,然后执行threadGuide()方法调用构造时候傳入的函数指针执行咱们想运行的函数实现Thread类.
这两个队列在线程池中的定义如下:
任务分配逻辑主要靠两个条件变量实现,(条件變量本文不做详述)
start()方法是线程池的运行方法.通过它创建线程池.
线程跑起来后,通过 isRunning 控制线程循环是否退出.
stop()方法关闭线程池,回收资源.
循环中判斷 : 有任务则执行,无任务则wait 阻塞等待.
Thread(threadRoutine, this) 这里就是为什么我线程类要带一个无符号类型指针参数的原因,因为静态函数无法调用c++的类成员函数(主要原因是类在编译期间未实例化没有明确的地址.)我们只能通过线程池对象的this指针调用它的成员.
创建一个有两个线程,拥有5个任务的任務队列,执行8个加数任务.