前面講了mysql的啟動,執行緒的初始化,執行緒池的基本原理,現在就看看工作執行緒都在迴圈中主要幹了什麼,順便說一下以後的方向,以後主要會學習mysql的cache原理,大約涉及到6000行左右的**,不知道什麼時候能搞清楚,之後就會進入innodb引擎,主要攻幾方面方面:innodb的檔案儲存結構,索引的實現,鎖的實現,事務的實現。
mysql的工作執行緒呼叫的函式棧很淺,如果我們在mysql不處理任何命令的情況下掛起整個mysql,那麼就可以觀察到mysql的工作執行緒都在等待或者幹什麼:
寫成偽**就是:
while(thd_is_connection_alive(thd))
mysql_audit_release(thd);if(do_command(thd))break;
就是這個while函式,在sql/source files/sql_connect.cc:867這個檔案中,mysql工作執行緒就是不停的堅持是否需要退出(thd_is_connection_alive),然後嘗試read出客戶端上發的指令,若沒有,那麼read阻塞,看來mysql是阻塞read的,一旦read夠足夠長的指令,那麼就會丟給sql_parse.cc的dispatch_command函式根據不同的指令執行對應的**。這裡就有必要看看客戶端上發的指令格式是怎麼樣子的了,先建立個簡單的表:
create tablecustomers(
idintauto_increment,
namevarchar(64) not null default '',
ageint not null default -1,
birthdaydatetime,primary keyidx_id(id)
)engine=innodb,charset=utf8;
以及插入若干資料,這個表將是未來我們主要的實驗表。經過閱讀**和測試發現,mysql的客戶端上發格式非常簡單,至少我目前還沒遇到複雜的格式,格式就是「命令」+「sql語句」。因為mysql和客戶端的交流是靠桌球方法交流的,也就是我發等你回,我回等你發,總之不是客戶端等服務的回就是服務端等客戶端發,在這個桌球交流中,「球」到了mysql服務端後,mysql先讀出前面四個位元組,這個四個位元組其實就是int,也就是即將收到的sql語句長度,更準確的說是前面提到的「命令」+「sql語句」,mysql就會read出這個長度的資訊出來。接著,mysql會把讀到的資訊儲存在thd->net->packet中,thd->net->packet_length則是這個格式的長度。再往後,mysql就會把這些資訊傳入dispatch_command函式進行解析執行了。
解析完成,會呼叫end_statement回給客戶端,mysql回的內容只有兩種,一種是錯誤碼,一種是查詢位元組流和查詢狀態,這些以後再細看。
總之mysql和客戶端就是這樣乙個桌球交流,自己也是不停的做以上這個迴圈,直到被通知停止為止。
主線程和子執行緒
子執行緒通過 handlerthread的thread.getlooper 繫結,在主線程的handler的handlermessage中呼叫threadhandler.sendmessagedelay msg,1000 向子執行緒傳送訊息。在子執行緒中通過handler.sendmessagede...
主線程和子執行緒
主線程負責管理由它建立的子執行緒,建立 啟動 掛起 停止等。主線程通過發訊息的方式管理子執行緒,例如,給子執行緒傳送start 訊息,子執行緒啟動,子執行緒執行入口的run 方法。thread有下面兩個構造方法 thread runnable target,string name thread ru...
mysql 執行緒池 Mysql 執行緒池
why 在5.6以前,mysql會對每個連線建立乙個執行緒,請求結束後銷毀執行緒。在高併發的情況下,為了避免頻繁建立和釋放連線,可以通過thread cache將執行緒快取起來,請求來了先嘗試從cache中獲取,重複利用執行緒資源。問題在低併發的情況下,thread cache可以成為乙個有效的優化...