C++ 池式组件 线程池 内存池 异步请求池 MySQL连接池
池式组件
- 线程池
- 线程池的作用
- 工作原理
- 线程池
- Nginx线程池
- 内存池
- 背景
- 链表法
- 方法
- 遇到的问题
- 固定内存块大小法
- 方法
- 遇到的问题
- 大块开小块
- 方法
- 异步请求池
- 请求组件
- 请求原理
- 请求池设计
- MySQL连接池
- 池化技术
- 连接池和线程池的关系
- 使用数据库连接池
线程池
线程池的作用
减少线程的创建和销毁 pthread_create()
异步解耦的作用 loginfo(“log”); 提高效率
工作原理
组件
create/init 线程池的初始化
push_task
destroy/deinit 线程池销毁
task_count 计算任务数量
free_thread 空闲线程数量
线程池
线程
任务
管理
Nginx线程池
计算密集型:
任务密集型:CPU的两倍或者更多
30%~70%:创建或者销毁线程
内存池
背景
避免频繁的分配内存
内存使用方式不对
不要自己造轮子,理解原理
jemalloc/tcmalloc
链表法
方法
- 链表链接内存块
遇到的问题
- 内存块越分越小
固定内存块大小法
方法
- 分配固定大小的块
- 16个字节 – 32 – 64 – 128 – …
遇到的问题
- 小块查找速度慢
- 内存块之间出现间隙 – 影响内存块的回收出现问题
大块开小块
方法
- 申请一个大块,从大块中申请小块
- 大块用完之后在申请一个大块
- 申请内存时加锁解决线程安全问题
- Invalid conversion from ‘void*’ to ‘unsigned char*’
异步请求池
请求组件
- 线程池
- 协程
- 异步请求池
请求原理
- 发送请求 多个IO
- 接受结果的线程,如何拿到fd:fd通过epoll_ctl添加到epoll
请求池设计
- commit
socket
connect server
encode --> redis/mysql/dns
send
fd 加入epoll_ctl
- thread_callback
while(1) {
epoll_wait();
recv();
parser();
fd --> epoll delete;
}
- init
epoll_create 初始化
pthread_create 线程初始化
- destroy
close(epfd);
pthread cancel;
遇到的问题
- 同步到异步
- warning: ISO C++ forbids converting a string constant to ‘char*‘ [-Wwrite-strings]
MySQL连接池
池化技术
- 对象创建时间长
- 对象创建消耗大量资源
- 对象创建之后可以重复利用
连接池和线程池的关系
- 线程池主动执行任务,连接池对象被人误获取,执行任务后归还。
使用数据库连接池
- 资源复用
- 更快的系统响应速度
- 统一的连接管理
使用连接池的优点
- 降低网络开销,提升性能
- 连接复用,有效减少连接数
- 没有TIME_WAIT状态的问题