日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
一起學(xué)習(xí)MySQL源碼筆記之偷窺線程

安裝完Mysql后,使用VS打開源碼開開眼,我嘞個(gè)去,這代碼和想象中怎么差別這么大呢?感覺代碼有些凌亂,注釋代碼都寫的比較隨意,好像沒有什么統(tǒng)一的規(guī)范,不同的文件中代碼風(fēng)格也有差異,可能Mysql經(jīng)過了很多牛人的手之后,集眾牛人之長吧。也可能是我見識(shí)比較淺薄,適應(yīng)了自己的代碼風(fēng)格,井底之蛙了,總之還是懷著敬畏的心情開始咱的源碼之旅吧。本人菜鳥,大神輕拍。

公司主營業(yè)務(wù):成都網(wǎng)站設(shè)計(jì)、成都網(wǎng)站建設(shè)、移動(dòng)網(wǎng)站開發(fā)等業(yè)務(wù)。幫助企業(yè)客戶真正實(shí)現(xiàn)互聯(lián)網(wǎng)宣傳,提高企業(yè)的競(jìng)爭(zhēng)能力。創(chuàng)新互聯(lián)公司是一支青春激揚(yáng)、勤奮敬業(yè)、活力青春激揚(yáng)、勤奮敬業(yè)、活力澎湃、和諧高效的團(tuán)隊(duì)。公司秉承以“開放、自由、嚴(yán)謹(jǐn)、自律”為核心的企業(yè)文化,感謝他們對(duì)我們的高要求,感謝他們從不同領(lǐng)域給我們帶來的挑戰(zhàn),讓我們激情的團(tuán)隊(duì)有機(jī)會(huì)用頭腦與智慧不斷的給客戶帶來驚喜。創(chuàng)新互聯(lián)公司推出丹陽免費(fèi)做網(wǎng)站回饋大家。

Mysql可以啟動(dòng)起來了,應(yīng)該怎么學(xué)習(xí)呢?總不能從main開始一步一步的看吧,Mysql作為比較底層的大型軟件,涉及到數(shù)據(jù)庫實(shí)現(xiàn)的方方面面,沒有厚實(shí)的數(shù)據(jù)庫理論基礎(chǔ)和對(duì)Mysql各個(gè)模塊相當(dāng)?shù)氖煜ぃ瑥膍ain開始勢(shì)必會(huì)把自己引入某個(gè)死胡同啊,什么都看,最后啥也不會(huì),咱傷不起。

經(jīng)過思考后,我想還是通過客戶端來調(diào)試服務(wù)器,從而學(xué)習(xí)服務(wù)器代碼比較現(xiàn)實(shí)。也就是通過客戶端的動(dòng)作,看服務(wù)器的反應(yīng)。比如從客戶端的登錄動(dòng)作來看SERVER如何進(jìn)行通信、用戶識(shí)別、鑒定以及任務(wù)分配的,通過CREATE TABLE,來看SERVER如何解析DDL語句以及針對(duì)不同的存儲(chǔ)引擎采取的不同的物理存儲(chǔ)方式,通過INSERT語句,來看SERVER如何進(jìn)行Btree的操作。通過SELECT語句來看如何進(jìn)行SQL語句語法樹的創(chuàng)建和優(yōu)化的,通過ROLL BACK,來看SERVER事務(wù)是如何實(shí)現(xiàn)的。這里主要是通過跟蹤代碼學(xué)習(xí)Mysql數(shù)據(jù)庫實(shí)現(xiàn)的思想,對(duì)于具體的代碼不去做過多的追究(主要是我對(duì)C++不是很熟悉),好讀書,不求甚解,呵呵。

由此,暫時(shí)準(zhǔn)備了以下幾條SQL語句,來有針對(duì)的進(jìn)行SERVER的分析

 
 
 
 
  1. 1、LOGIN(登錄) 
  2. mysql.exe –uroot –p
  3. 2、DDL(建表語句)
  4. create table tb_myisam(c1 int, c2 varchar(256)) engine = myisam;
  5. create table tb_innodb(c1 int, c2 varchar(256)) engine = innodb;
  6. 3、INSERT
  7. Insert into tb_myisam values(1 , ’寂寞的肥肉’);
  8. Insert into tb_innodb values(1 , ’寂寞的肥肉’);
  9. 4、SELECT
  10. Select c1 from tb_myisam;
  11. Select * from tb_innodb;
  12. 5、ROLLBACK

大家都知道,mysql可以通過多個(gè)客戶端,進(jìn)行并發(fā)操作,當(dāng)然也包括登錄了。在別人登錄的時(shí)候,其他的用戶可能正在進(jìn)行一些其它的操作,因此對(duì)于登錄我們猜測(cè)應(yīng)該有專門的線程負(fù)責(zé)客戶端和服務(wù)器的連接的創(chuàng)建,以保證登錄的及時(shí)性,對(duì)于每個(gè)連接的用戶,應(yīng)該用一個(gè)獨(dú)立的線程進(jìn)行任務(wù)的執(zhí)行。

首先介紹下mysql中創(chuàng)建線程的函數(shù),創(chuàng)建線程的函數(shù)貌似就是_begin_thread,CreateThread,我們通過VS在整個(gè)解決方案中進(jìn)行查找,bingo!在my_winthread.c中找到了調(diào)用_begin_thread的函數(shù)pthread_create,在os0thread.c中找到了調(diào)用CreateThread的函數(shù)os_thread_create,一個(gè)系統(tǒng)怎么封裝兩個(gè)系統(tǒng)函數(shù)呢??再仔細(xì)看下,發(fā)現(xiàn)my_winthread.c是在項(xiàng)目mysys下,而os0thread.c是在項(xiàng)目innobase下。innobase??!這不就是innodb的插件式存儲(chǔ)引擎么,原來這是存儲(chǔ)引擎自己的封裝的底層函數(shù),哥心中豁然開朗了。我想Mysql應(yīng)用范圍如此之廣,除了開源之外,插件式的存儲(chǔ)引擎功不可沒啊,用戶可以根據(jù)自己的實(shí)際應(yīng)用采取不同的存儲(chǔ)引擎,對(duì)于大公司,估計(jì)會(huì)開發(fā)自己的存儲(chǔ)引擎。

下面分析下pthread_create是如何調(diào)用_begin_thread的,先粗略看下源碼。

 
 
 
 
  1. int pthread_create(pthread_t *thread_id, pthread_attr_t *attr,
  2.    pthread_handler func, void *param)
  3. {
  4.   HANDLE hThread;
  5.   struct pthread_map *map;
  6.   DBUG_ENTER("pthread_create");
  7.   if (!(map=malloc(sizeof(*map))))
  8.     DBUG_RETURN(-1);
  9.   map->func=func;
  10.   map->param=param;
  11.   pthread_mutex_lock(&THR_LOCK_thread);
  12. #ifdef __BORLANDC__
  13.   hThread=(HANDLE)_beginthread((void(_USERENTRY *)(void *)) pthread_start,
  14.                    attr->dwStackSize ? attr->dwStackSize :
  15.                    65535, (void*) map);
  16. #else
  17.   hThread=(HANDLE)_beginthread((void( __cdecl *)(void *)) pthread_start,
  18.                    attr->dwStackSize ? attr->dwStackSize :
  19.                    65535, (void*) map);
  20. #endif
  21.   DBUG_PRINT("info", ("hThread=%lu",(long) hThread));
  22.   *thread_id=map->pthreadself=hThread;
  23.   pthread_mutex_unlock(&THR_LOCK_thread);
  24.   if (hThread == (HANDLE) -1)
  25.   {
  26.     int error=errno;
  27.     DBUG_PRINT("error",
  28.            ("Can't create thread to handle request (error %d)",error));
  29.     DBUG_RETURN(error ? error : -1);
  30.   }
  31.   VOID(SetThreadPriority(hThread, attr->priority)) ;
  32.   DBUG_RETURN(0);
  33. }

關(guān)鍵的代碼是下面三句:

 
 
 
 
  1. map->func=func;
  2. map->param=param;
  3. _beginthread((void( __cdecl *)(void *)) pthread_start,
  4.                    attr->dwStackSize ? attr->dwStackSize :
  5.                    65535, (void*) map); 

從這可以看出,創(chuàng)建的新線程的名字是個(gè)固定的函數(shù)——pthread_start,而我們傳進(jìn)來的想創(chuàng)建的函數(shù)func是掛載在了map上了,函數(shù)的參數(shù)同樣的掛載在map上了,這樣我們就可以推理出在pthread_start函數(shù)中,肯定會(huì)出現(xiàn)這樣的代碼:

 
 
 
 
  1. map->func(map->param);

mysql沒有選擇直接_beginthread(func, stack_size, param)的形式,而是進(jìn)行了一次封裝,不知道這樣的好處是什么,可能牛人的思想不是我這樣小菜鳥能頓悟的,跑題了~~

至此,我們只在pthread_create函數(shù)上設(shè)置斷點(diǎn),調(diào)試啟動(dòng)mysqld,斷點(diǎn)停下來,看下系統(tǒng)的線程狀況:

我們第一次進(jìn)入pthread_create,任何線程都沒開始創(chuàng)建呢,按理說系統(tǒng)線程應(yīng)該就只有一個(gè)主線程,可現(xiàn)在多了這么多,這些應(yīng)該是innodb存儲(chǔ)引擎創(chuàng)建的線程了(具體是在plugin_init)。根據(jù)線程的名稱,結(jié)合注釋,猜測(cè)了下這些線程的作用。

 Io_handler_thread:從名稱可以知道這些是I/O線程,負(fù)責(zé)進(jìn)行磁盤I/O。

   Svr_error_monitor_thread:應(yīng)該是服務(wù)器出錯(cuò)監(jiān)控線程。

   Svr_lock_timeout_thread:應(yīng)該是和上鎖相關(guān)的線程。

   Svr_master_thread:

/*************************************************************************

The master thread controlling the server. */

   服務(wù)器控制線程,應(yīng)該是具體進(jìn)行作業(yè)的線程。

   Svr_monitor_thread:

/*************************************************************************

A thread prints the info output by various InnoDB monitors. */

   監(jiān)控線程,負(fù)責(zé)打印信息。

淡然飄過吧,不去細(xì)究了,我們只關(guān)心pthread_create創(chuàng)建的線程。根據(jù)調(diào)試,發(fā)現(xiàn)多了幾個(gè)線程同名的線程_threadstart,如下所示:

調(diào)試時(shí)看堆??梢灾肋@三個(gè)線程的創(chuàng)建者和作用,如下所示

創(chuàng)建者 處理函數(shù)
create_shutdown_thread handle_shutdown
start_handle_manager  handle_manager
handle_connections_methods  handle_connections_sockets

創(chuàng)建者:調(diào)用pthread_create進(jìn)行創(chuàng)建線程的函數(shù)。

處理函數(shù):調(diào)用pthread_create所創(chuàng)建的線程的具體的線程函數(shù)。

由名稱我們就可以看出,handle_connections_sockets應(yīng)該是處理連接的線程了,從順序上看,也應(yīng)該是這樣,只有系統(tǒng)中所有的其他必須的線程創(chuàng)建完畢后,才能創(chuàng)建監(jiān)聽線程(連接線程),即監(jiān)聽線程應(yīng)該是系統(tǒng)最后創(chuàng)建的。

找到了我們LOGIN需要的線程了,下次針對(duì)這個(gè)線程,分析下如何進(jìn)行登錄的,以及登錄后為用戶分配哪些資源。時(shí)間不早啦,洗洗睡了


分享題目:一起學(xué)習(xí)MySQL源碼筆記之偷窺線程
URL地址:http://www.5511xx.com/article/coedhpj.html