C++中有三大池,即我们常说的:线程池,内存池,数据库连接池。
一.线程池
多线程同时访问共享资源造成数据混乱的原因就是因为CPU的上下文切换导致,线程池就是为了解决此问题而生。
多线程常用的有:std::thread、Boost.Thread库,以及Qt提供线程池类QThread。
线程池的结构,手写线程池设计思路:
1.设计任务的结构体,及任务队列,存储需要处理的任务,后面由工作的线程来处理这些任务:
设计一个任务结构体struct或者class;
设计基于管理任务的队列queue的类,包含添加任务,删除任务,取出任务;
2.设计工作的线程(任务队列任务的消费者),N个:
线程池维护一定数量的工作现场,以不停的取出任务并处理
工作的线程充当任务的消费者角色
任务队列为空时,工作的线程将被阻塞
有了新任务时,生产者将解出阻塞,让工作线程开始工作;
3.管理者线程(不处理任务队列中的任务),1个:
管理者线程主要检测任务队列中的任务数量和处于繁忙状态的工作线程
任务多的时候适当创建新的工作线程,任务少的时候适当销毁一些工作线程
按照设定的工作线程量的最大最小个数来控制工作线程的个数。
二.内存池
1.内存池的作用:解决内存碎片问题,提高内存申请分配效率,防止内存泄漏和野指针;
2.使用:可以使用Boost库和Jemalloc库的内存池,也可以自己手写内存池;
3.设计原理:
预分配内存:先申请一大块内存,根据情况划分成多个小的内存块
初始化内存块链表:将整体内存里的所有内存块包括各自的地址和状态信息,放入一个链表来维护
实现内存分配函数:当采购员宣布内存请求时,分配函数从内存链表中找到一块可用的内存,返回内存块的地址;
实现内存释放函数:当用完内存块后,将内存块中的数据清空并将该块内存加入到内存链表中并将其状态改为可用;
实现内存整理函数:内存整理是将连续可用的内存块合并为一个大的内存块,或者将某个大的内存块分割成多个小的内存块,以提高使用效率
三.数据库连接池
连接池是一个单例模式的类
所有的连接任务都放到一个队列中,可以用STL的Queue
使用互斥锁来保护队列的线程安全
可以从连接池中得到一个或多个可用的数据库连接
如果队列中没有多余的可用连接,需要动态的创建新连接
如果队列中空闲的连接太多,需要动态的销毁一部分
数据库操作完毕,需要将连接归还到连接池中