目錄
one-connection-per-thread
线程池与epoll
线程池函数调用关系
one-connection-per-thread函数调用关系
首頁 資料庫 mysql教程 MySQL详解(8)----------MySQL线程池总结(二)_MySQL

MySQL详解(8)----------MySQL线程池总结(二)_MySQL

Jun 01, 2016 pm 12:59 PM
執行緒

这篇文章是对上篇文章的一个补充,主要围绕以下两点展开,one-connection-per-thread的实现方式以及线程池中epoll的使用。

one-connection-per-thread

根据scheduler_functions的模板,我们也可以列出one-connection-per-thread方式的几个关键函数。

static scheduler_functions con_per_functions=

{ max_connection+1, // max_threads

NULL,

NULL,

NULL, // init

Init_new_connection_handler_thread, // init_new_connection_thread

create_thread_to_handle_connection, // add_connection

NULL, // thd_wait_begin

NULL, // thd_wait_end

NULL, // post_kill_notification

one_thread_per_connection_end, // end_thread

NULL // end

};
登入後複製

1.init_new_connection_handler_thread

这个接口比较简单,主要是调用pthread_detach,将线程设置为detach状态,线程结束后自动释放所有资源。

2.create_thread_to_handle_connection

这个接口是处理新连接的接口,对于线程池而言,会从thread_id%group_size对应的group中获取一个线程来处理,而one-connection-per-thread方式则会判断是否有thread_cache可以使用,如果没有则新建线程来处理。具体逻辑如下:

(1).判断缓存的线程数是否使用完(比较blocked_pthread_count 和wake_pthread大小)

(2).若还有缓存线程,将thd加入waiting_thd_list的队列,唤醒一个等待COND_thread_cache的线程

(3).若没有,创建一个新的线程处理,线程的入口函数是do_handle_one_connection

(4).调用add_global_thread加入thd数组。

3.do_handle_one_connection

这个接口被create_thread_to_handle_connection调用,处理请求的主要实现接口。

(1).循环调用do_command,从socket中读取网络包,并且解析执行;

(2). 当远程客户端发送关闭连接COMMAND(比如COM_QUIT,COM_SHUTDOWN)时,退出循环

(3).调用close_connection关闭连接(thd->disconnect());

(4).调用one_thread_per_connection_end函数,确认是否可以复用线程

(5).根据返回结果,确定退出工作线程还是继续循环执行命令。

4.one_thread_per_connection_end

判断是否可以复用线程(thread_cache)的主要函数,逻辑如下:

(1).调用remove_global_thread,移除线程对应的thd实例

(2).调用block_until_new_connection判断是否可以重用thread

(3).判断缓存的线程是否超过阀值,若没有,则blocked_pthread_count++;

(4).阻塞等待条件变量COND_thread_cache

(5).被唤醒后,表示有新的thd需要重用线程,将thd从waiting_thd_list中移除,使用thd初始化线程的thd->thread_stack

(6).调用add_global_thread加入thd数组。

(7).如果可以重用,返回false,否则返回ture

线程池与epoll

在引入线程池之前,server层只有一个监听线程,负责监听mysql端口和本地unixsocket的请求,对于每个新的连接,都会分配一个独立线程来处理,因此监听线程的任务比较轻松,mysql通过poll或select方式来实现IO的多路复用。引入线程池后,除了server层的监听线程,每个group都有一个监听线程负责监听group内的所有连接socket的连接请求,工作线程不负责监听,只处理请求。对于overscribe为1000的线程池设置,每个监听线程需要监听1000个socket的请求,监听线程采用epoll方式来实现监听。

Select,poll,epoll都是IO多路复用机制,IO多路复用通过一种机制,可以监听多个fd(描述符),比如socket,一旦某个fd就绪(读就绪或写就绪),能够通知程序进行相应的读写操作。epoll相对于select和poll有了很大的改进,首先epoll通过epoll_ctl函数注册,注册时,将所有fd拷贝进内核,只拷贝一次不需要重复拷贝,而每次调用poll或select时,都需要将fd集合从用户空间拷贝到内核空间(epoll通过epoll_wait进行等待);其次,epoll为每个描述符指定了一个回调函数,当设备就绪时,唤醒等待者,通过回调函数将描述符加入到就绪链表,无需像select,poll方式采用轮询方式;最后select默认只支持1024个fd,epoll则没有限制,具体数字可以参考cat /proc/sys/fs/file-max的设置。epoll贯穿在线程池使用的过程中,下面我就epoll的创建,使用和销毁生命周期来描述epoll在线程中是如何使用的。

线程池初始化,epoll通过epoll_create函数创建epoll文件描述符,实现函数是thread_group_init;端口监听线程监听到请求后,创建socket,并创建THD和connection对象,放在对应的group队列中;工作线程获取该connection对象时,若还未登录,则进行登录验证若socket还未注册到epoll,则调用epoll_ctl进行注册,注册方式是EPOLL_CTL_ADD,并将connection对象放入epoll_event结构体中若是老连接的请求,仍然需要调用epoll_ctl注册,注册方式是EPOLL_CTL_MODgroup内的监听线程调用epoll_wait来监听注册的fd,epoll是一种同步IO方式,所以会进行等待请求到来时,获取epoll_event结构体中的connection,放入到group中的队列线程池销毁时,调用thread_group_close将epoll关闭。

备注:

1.注册在epoll的fd,若请求就绪,则将对应的event放入到events数组,并将该fd的事务类型清空,因此对于老的连接请求,依然需要调用epoll_ctl(pollfd, EPOLL_CTL_MOD, fd, &ev)来注册。

线程池函数调用关系

(1)创建epoll

tp_init->thread_group_init->tp_set_threadpool_size->io_poll_create->epoll_create

(2)关闭epoll

tp_end->thread_group_close->thread_group_destroy->close(pollfd)

(3)关联socket描述符

handle_event->start_io->io_poll_associate_fd->io_poll_start_read->epoll_ctl

(4)处理连接请求

handle_event->threadpool_process_request->do_command->dispatch_command->mysql_parse->mysql_execute_command

(5)工作线程空闲时

worker_main->get_event->pthread_cond_timedwait

等待thread_pool_idle_timeout后,退出。

(6)监听epoll

worker_main->get_event->listener->io_poll_wait->epoll_wait

(7)端口监听线程

main->mysqld_main->handle_connections_sockets->poll

one-connection-per-thread函数调用关系

(1) 工作线程等待请求

handle_one_connection->do_handle_one_connection->do_command->

my_net_read->net_read_packet->net_read_packet_header->net_read_raw_loop->

vio_read->vio_socket_io_wait->vio_io_wait->poll

备注:与线程池的工作线程有监听线程帮助其监听请求不同,one-connection-per-thread方式的工作线程在空闲时,会调用poll阻塞等待网络包过来;

而线程池的工作线程只需要专心处理请求即可,所以使用也更充分。

(2)端口监听线程

与线程池的(7)相同

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1664
14
CakePHP 教程
1422
52
Laravel 教程
1316
25
PHP教程
1267
29
C# 教程
1239
24
8核16線程是什麼意思? 8核16線程是什麼意思? Feb 02, 2023 am 11:26 AM

8核是指CPU有8顆物理核心,16線程是指CPU最多同時可以有16個執行緒處理任務。核心數和執行緒數是電腦CPU的重要效能指標,CPU的核心數越高處理速度就越高;執行緒數越多越有利於同時運行多個程序,因為執行緒數等同於在某個瞬間CPU能同時並行處理的任務數。多執行緒可最大限度地實現寬發射、亂序的超標量處理,提高處理器運算元件的使用率,緩和由於資料相關或Cache未命中帶來的存取記憶體延遲。

C++並發程式設計:如何避免執行緒飢餓和優先反轉? C++並發程式設計:如何避免執行緒飢餓和優先反轉? May 06, 2024 pm 05:27 PM

為避免執行緒飢餓,可以使用公平鎖確保資源公平分配,或設定執行緒優先權。為解決優先權反轉,可使用優先權繼承,即暫時提高持有資源執行緒的優先權;或使用鎖的提升,即提升需要資源執行緒的優先權。

go語言中協程與執行緒的差別是什麼 go語言中協程與執行緒的差別是什麼 Feb 02, 2023 pm 06:10 PM

區別:1、一個執行緒可以多個協程,一個行程也可以單獨擁有多個協程;2、執行緒是同步機制,而協程則是異步;3、協程能保留上一次呼叫時的狀態,執行緒不行;4、執行緒是搶佔式,協程是非搶佔式的;5、執行緒是被分割的CPU資源,協程是組織好的程式碼流程,協程需要執行緒來承載運作。

C++並發程式設計:如何進行執行緒終止和取消? C++並發程式設計:如何進行執行緒終止和取消? May 06, 2024 pm 02:12 PM

C++中執行緒終止和取消機制包括:執行緒終止:std::thread::join()阻塞目前執行緒直到目標執行緒完成執行;std::thread::detach()從執行緒管理中分離目標執行緒。執行緒取消:std::thread::request_termination()請求目標執行緒終止執行;std::thread::get_id()取得目標執行緒ID,可與std::terminate()一起使用,立即終止目標執行緒。實戰中,request_termination()允許執行緒決定終止時機,join()確保在主線

什麼是程式運行時指令流的最小單位 什麼是程式運行時指令流的最小單位 Aug 23, 2022 pm 02:16 PM

「執行緒」是程式運行時指令流的最小單位。進程是指一個具有一定獨立功能的程序,而執行緒是進程的一部分,描述指令流執行狀態;執行緒是進程中的指令執行流的最小單位,是CPU調度的基本單位。一個執行緒是一個任務(一個程式段)的一次執行過程;執行緒不佔有記憶體空間,它包括在一個行程的記憶體空間中。在同一個行程內,多個執行緒共享行程的資源;一個行程至少有一個執行緒。

Microsoft計畫在Windows上的Outlook經典應用程式中引入AI驅動的Copilot Microsoft計畫在Windows上的Outlook經典應用程式中引入AI驅動的Copilot Oct 19, 2023 pm 11:13 PM

Microsoft顯然不會將其強大的人工智慧支援的Copilot工具保留為新應用程式的獨家功能。現在,該公司剛剛宣布計劃在Windows上的Outlook經典應用程式中引入Copilot。正如其365路線圖網站上發布的那樣,預覽將於明年<>月開始,直到<>月在當前頻道的桌面上在全球範圍內推出。 Copilot是一種生產力工具,它使用大型語言模型(LLM)來幫助使用者完成編寫電子郵件、匯總文件和翻譯語言等任務。它的主要功能之一是它能夠總結電子郵件

Java錯誤:JavaFX線程卡頓錯誤,如何處理和避免 Java錯誤:JavaFX線程卡頓錯誤,如何處理和避免 Jun 24, 2023 pm 05:52 PM

在進行JavaFX應用程式開發的過程中,我們常常會遇到JavaFX執行緒卡頓錯誤。這種錯誤的嚴重程度不同,可能會對程式的穩定性和效能產生不利的影響。為了確保程式的正常運行,我們需要了解JavaFX執行緒卡頓錯誤的原因和解決方法,以及如何預防這種錯誤的發生。一、JavaFX線程卡頓錯誤的原因JavaFX是一個多線程的UI應用程式框架,它允許程式在後台執行緒執行長時

Go語言中線程和進程的區別解析 Go語言中線程和進程的區別解析 Apr 03, 2024 pm 01:39 PM

Go語言中的進程和執行緒:進程:獨立運行的程式實例,擁有自己的資源和位址空間。執行緒:進程內的執行單元,共享行程資源和位址空間。特點:進程:開銷大,隔離性好,獨立調度。執行緒:開銷小,共享資源,內部調度。實戰案例:進程:隔離長時間運行的任務。線程:並發處理大量資料。

See all articles