数据库学*笔记三:MySQL中的线程连接方式

发布于:2021-10-27 18:12:36

1、线程池


线程看做系统资源那么线程池本质上是对系统资源的管理,对于操作系统来说线程的创建和销毁是比较消耗系统资源的,频繁的创建与销毁线程必然给系统带来不必要的资源浪费,特别是在负载高的情况下这部分开销严重影响系统的资源使用效率从而影响系统的性能与吞吐量,另一方面过多的线程创建又会造成系统资源的过载消耗,同时带来相对频繁的线程之间上下文切换问题。


2、Mysql-Server支持3种连接管理方式


No-Threads、One-Thread-Per-Connection、Pool-Threads。连接管理方式通过thread_handling参数控制:



if (thread_handling <= SCHEDULER_ONE_THREAD_PER_CONNECTION)
one_thread_per_connection_scheduler(thread_scheduler,
&max_connections,&connection_count);
else if (thread_handling == SCHEDULER_NO_THREADS)
one_thread_scheduler(thread_scheduler);
else
pool_of_threads_scheduler(thread_scheduler, &max_connections,&connection_count);
3、
连接管理流程
? 通过poll监听mysql端口的连接请求
? ?收到连接后,调用accept接口,创建通信socket
? ?初始化thd实例,vio对象等
? ?根据thread_handling方式设置,初始化thd实例的scheduler函数指针
? ?调用scheduler特定的add_connection函数新建连接


4、线程池的实现框架


每个group包含一个优先队列和普通队列,包含一个listener线程和若干个工作线程,listener线程和worker线程可以动态转换,worker线程数目由工作负载决定,整个线程池有一个timer线程监控group,防止group“停滞”。


5、线程池工作接口



tp_add_connection[处理新连接]



1) 创建一个connection对象


2) 根据thread_id%group_count确定connection分配到哪个group


3) 将connection放进对应group的队列


4) 如果当前活跃线程数为0,则创建一个工作线程


worker_main[工作线程]



1) 调用get_event获取请求


2) 如果存在请求,则调用handle_event进行处理


3) 否则,表示队列中已经没有请求,退出结束。


get_event[获取请求]



1) 获取一个连接请求


2) 如果存在,则立即返回,结束


3) 若此时group内没有listener,则线程转换为listener线程,阻塞等待


4) 若存在listener,则将线程加入等待队列头部


5) 线程休眠指定的时间(thread_pool_idle_timeout)


6) 如果依然没有被唤醒,是超时,则线程结束,结束退出


7) 否则,表示队列里有连接请求到来,跳转1


handle_event[处理请求]



1) 判断连接是否进行登录验证,若没有,则进行登录验证


2) 关联thd实例信息


3) 获取网络数据包,分析请求


4) 调用do_command函数循环处理请求


5) 获取thd实例的套接字句柄,判断句柄是否在epoll的监听列表中


6) 若没有,调用epoll_ctl进行关联


7) 结束


listener[监听线程]



1) 调用epoll_wait进行对group关联的套接字监听,阻塞等待


2) 若请求到来,从阻塞中恢复


3) 根据连接的优先级别,确定是放入普通队列还是优先队列


4) 判断队列中任务是否为空


5) 若队列为空,则listener转换为worker线程


6) 若group内没有活跃线程,则唤醒一个线程


timer_thread[监控线程]



1) 若没有listener线程,并且最*没有io_event事件


2) 则创建一个唤醒或创建一个工作线程


3) 若group最*一段时间没有处理请求,并且队列里面有请求,则


4) 表示group已经stall,则唤醒或创建线程


5)检查是否有连接超时


tp_wait_begin[进入等待状态流程]



1) active_thread_count减1,waiting_thread_count加1


2)设置connection->waiting= true


3) 若活跃线程数为0,并且任务队列不为空,或者没有监听线程,则


4) 唤醒或创建一个线程


tp_wait_end[结束等待状态流程]



1) 设置connection的waiting状态为false


2) active_thread_count加1,waiting_thread_count减1


tp_init/tp_end


分别调用thread_group_init和thread_group_close来初始化和销毁线程池

相关推荐

最新更新

猜你喜欢