本發(fā)明涉及操作系統(tǒng)技術(shù)領(lǐng)域,特別是涉及一種線程調(diào)度方法和裝置。
背景技術(shù):
棋牌游戲開發(fā)中,普遍使用多進(jìn)程單線程模型作為服務(wù)器的基本架構(gòu),使用多進(jìn)程可以由調(diào)度程序?qū)碜钥蛻舳说恼埱筮M(jìn)行分流,避免單一進(jìn)程處理量過大,同時(shí),更好地利用了cpu(centralprocessingunit,中央處理器)的工作效率,使用單線程,可以避免進(jìn)程運(yùn)行過程中線程切換帶來的系統(tǒng)開銷,同時(shí)單線程情況下不存在死鎖現(xiàn)象,簡化了編碼流程,加快了游戲開發(fā)速度。但同時(shí),單線程模型的程序也有缺點(diǎn),比如,因?yàn)槟撤N原因需要同步數(shù)據(jù)而造成線程阻塞,則該線程只能處于休眠狀態(tài),等待數(shù)據(jù)返回才能重新喚醒該線程繼續(xù)處理邏輯,在這個(gè)休眠的過程中,它不會對其它請求進(jìn)行處理,這樣會影響其它請求的響應(yīng)速度。而在一個(gè)游戲中,往往伴隨著復(fù)雜的處理和各種數(shù)據(jù)的同步,若使用單線程模型,如果同步數(shù)據(jù)所需的時(shí)間越長,則線程處于休眠狀態(tài)的時(shí)間也越長,對其它請求的處理也就會相應(yīng)變慢。
技術(shù)實(shí)現(xiàn)要素:
基于此,有必要針對問題,提供一種線程調(diào)度方法,能夠在減少進(jìn)程運(yùn)行中線程切換帶來系統(tǒng)開銷的同時(shí)提高服務(wù)器處理客戶端請求的速度。
此外,還有必要針對問題,提供一種線程調(diào)度裝置,能夠在減少進(jìn)程運(yùn)行中線程切換帶來系統(tǒng)開銷的同時(shí)提高服務(wù)器處理客戶端請求的速度。
一種線程調(diào)度方法,包括以下步驟:
啟動(dòng)第一線程和第二線程,并使所述第二線程進(jìn)入休眠狀態(tài);
通過所述第一線程監(jiān)聽客戶端請求;
通過所述第一線程判斷所述客戶端請求是否為同步數(shù)據(jù)請求;
若否,則通過所述第一線程處理所述客戶端請求,并將處理結(jié)果返回客戶 端;
若是,則通過所述第一線程喚醒所述第二線程,以使所述第二線程處理所述客戶端請求,并將處理結(jié)果返回客戶端。
在其中一個(gè)實(shí)施例中,所述通過所述第一線程喚醒所述第二線程,以使所述第二線程處理所述客戶端請求,并將處理結(jié)果返回客戶端,具體包括:
通過所述第一線程獲取與所述客戶端請求相關(guān)的數(shù)據(jù);
將與所述客戶端請求相關(guān)的數(shù)據(jù)存儲在預(yù)設(shè)的數(shù)據(jù)容器中;
通過所述第一線程喚醒所述第二線程;
通過所述第二線程讀取所述數(shù)據(jù)容器的數(shù)據(jù),根據(jù)讀取的數(shù)據(jù)進(jìn)行相應(yīng)處理,并將處理結(jié)果返回客戶端。
在其中一個(gè)實(shí)施例中,所述將與所述客戶端請求相關(guān)的數(shù)據(jù)存儲在預(yù)設(shè)的數(shù)據(jù)容器中,具體為:
將所述與所述客戶端請求相關(guān)的數(shù)據(jù)按照預(yù)設(shè)的數(shù)據(jù)格式通過鏈表的形式存儲在預(yù)設(shè)的數(shù)據(jù)容器中;
所述與所述客戶端請求相關(guān)的數(shù)據(jù)包括客戶端身份標(biāo)識、第一線程運(yùn)算結(jié)果及所需訪問的同步數(shù)據(jù)。
在其中一個(gè)實(shí)施例中,所述通過所述第二線程讀取所述數(shù)據(jù)容器的數(shù)據(jù),根據(jù)讀取的數(shù)據(jù)進(jìn)行相應(yīng)處理,并將處理結(jié)果返回客戶端,具體包括:
通過所述第二線程讀取所述數(shù)據(jù)容器中的任務(wù),所述任務(wù)通過所述預(yù)設(shè)的數(shù)據(jù)格式表示;
使所述第二線程根據(jù)所述任務(wù)的所需訪問的同步數(shù)據(jù)從第三方同步接口中獲取所述同步數(shù)據(jù);
使所述第二線程根據(jù)所述任務(wù)的第一線程運(yùn)算結(jié)果及所述同步數(shù)據(jù)進(jìn)行運(yùn)算;
使所述第二線程根據(jù)所述任務(wù)的客戶端身份標(biāo)識將運(yùn)算結(jié)果返回給客戶端。
在其中一個(gè)實(shí)施例中,在使所述第二線程根據(jù)所述任務(wù)的客戶端身份標(biāo)識將運(yùn)算結(jié)果返回給客戶端的步驟之后,還包括:
將從數(shù)據(jù)容器中讀取并處理的任務(wù)從所述數(shù)據(jù)容器中移除;
通過所述第二線程判斷所述數(shù)據(jù)容器中是否還有未處理的任務(wù),若是,則使所述第二線程繼續(xù)讀取所述數(shù)據(jù)容器中的任務(wù)并處理,若否,則使所述第二線程進(jìn)入休眠狀態(tài)。
一種線程調(diào)度裝置,包括:
啟動(dòng)模塊,用于啟動(dòng)第一線程和第二線程,并使所述第二線程進(jìn)入休眠狀態(tài);
監(jiān)聽模塊,用于通過所述第一線程監(jiān)聽客戶端請求;
判斷模塊,用于通過所述第一線程判斷所述客戶端請求是否為同步數(shù)據(jù)請求;
第一處理模塊,用于當(dāng)所述第一線程判斷出所述客戶端請求不是同步數(shù)據(jù)請求時(shí),則通過所述第一線程處理所述客戶端請求,并將處理結(jié)果返回客戶端;
第二處理模塊,用于當(dāng)所述第一線程判斷出所述客戶端請求是同步數(shù)據(jù)請求時(shí),則通過所述第一線程喚醒所述第二線程,以使所述第二線程處理所述客戶端請求,并將處理結(jié)果返回客戶端。
在其中一個(gè)實(shí)施例中,所述第二處理模塊包括:
獲取單元,用于通過所述第一線程獲取與所述客戶端請求相關(guān)的數(shù)據(jù);
存儲單元,用于將與所述客戶端請求相關(guān)的數(shù)據(jù)存儲在預(yù)設(shè)的數(shù)據(jù)容器中;
喚醒單元,用于通過所述第一線程喚醒所述第二線程;
處理單元,用于通過所述第二線程讀取所述數(shù)據(jù)容器的數(shù)據(jù),根據(jù)讀取的數(shù)據(jù)進(jìn)行相應(yīng)處理,并將處理結(jié)果返回客戶端。
在其中一個(gè)實(shí)施例中,所述存儲單元還用于將所述與所述客戶端請求相關(guān)的數(shù)據(jù)按照預(yù)設(shè)的數(shù)據(jù)格式通過鏈表的形式存儲在預(yù)設(shè)的數(shù)據(jù)容器中;
所述與所述客戶端請求相關(guān)的數(shù)據(jù)包括客戶端身份標(biāo)識、第一線程運(yùn)算結(jié)果及所需訪問的同步數(shù)據(jù)。
在其中一個(gè)實(shí)施例中,所述處理單元包括:
讀取子單元,用于通過所述第二線程讀取所述數(shù)據(jù)容器中的任務(wù),所述任 務(wù)通過所述預(yù)設(shè)的數(shù)據(jù)格式表示;
獲取子單元,用于使所述第二線程根據(jù)所述任務(wù)的所需訪問的同步數(shù)據(jù)從第三方同步接口中獲取所述同步數(shù)據(jù);
運(yùn)算子單元,用于使所述第二線程根據(jù)所述任務(wù)的第一線程運(yùn)算結(jié)果及所述同步數(shù)據(jù)進(jìn)行運(yùn)算;
返回子單元,用于使所述第二線程根據(jù)所述任務(wù)的客戶端身份標(biāo)識將運(yùn)算結(jié)果返回給客戶端。
在其中一個(gè)實(shí)施例中,所述處理單元還包括:
移除子單元,用于將從數(shù)據(jù)容器中讀取并處理的任務(wù)從所述數(shù)據(jù)容器中移除;
判斷子單元,用于通過所述第二線程判斷所述數(shù)據(jù)容器中是否還有未處理的任務(wù),若是,則使所述第二線程繼續(xù)讀取所述數(shù)據(jù)容器中的任務(wù)并處理,若否,則使所述第二線程進(jìn)入休眠狀態(tài)。
上述線程調(diào)度方法和裝置,當(dāng)?shù)谝痪€程監(jiān)聽到同步數(shù)據(jù)請求,即當(dāng)?shù)谝痪€程監(jiān)聽到會造成線程阻塞的客戶端請求時(shí),喚醒第二線程,由第二線程處理該客戶端請求,可以有效區(qū)分阻塞型業(yè)務(wù)和非阻塞型業(yè)務(wù),進(jìn)而采用不同流程進(jìn)行處理,能夠在減少進(jìn)程運(yùn)行中線程切換帶來系統(tǒng)開銷的同時(shí)提高服務(wù)器處理客戶端請求的速度,有效提高客戶端的訪問速度。
附圖說明
圖1為一個(gè)實(shí)施例中線程調(diào)度方法的步驟示意圖;
圖2為一個(gè)實(shí)施例中通過第一線程喚醒第二線程,使第二線程處理客戶端請求的步驟示意圖;
圖3為一個(gè)實(shí)施例中通過第二線程處理數(shù)據(jù)容器中的任務(wù)的步驟示意圖;
圖4為一個(gè)實(shí)施例中數(shù)據(jù)容器的存儲結(jié)構(gòu)示意圖;
圖5為一個(gè)實(shí)施例中線程調(diào)度裝置的結(jié)構(gòu)示意圖;
圖6為一個(gè)實(shí)施例中第二處理模塊的內(nèi)部結(jié)構(gòu)示意圖;
圖7為一個(gè)實(shí)施例中處理單元的內(nèi)部結(jié)構(gòu)示意圖。
具體實(shí)施方式
為了使本發(fā)明的目的、技術(shù)方案及優(yōu)點(diǎn)更加清楚明白,以下結(jié)合附圖及實(shí)施例,對本發(fā)明進(jìn)行進(jìn)一步詳細(xì)說明。應(yīng)當(dāng)理解,此處所描述的具體實(shí)施例僅用以解釋本發(fā)明,并不用于限定本發(fā)明。
如圖1所示,一種線程調(diào)度方法,包括以下步驟:
步驟s110,啟動(dòng)第一線程和第二線程,并使第二線程進(jìn)入休眠狀態(tài)。
具體的,進(jìn)程是程序的基本執(zhí)行實(shí)體,是指令、數(shù)據(jù)及其組織形式的描述,進(jìn)程是程序的實(shí)體。線程是程序中一個(gè)單一的順序控制流程,是進(jìn)程內(nèi)一個(gè)相對獨(dú)立的、可調(diào)度的執(zhí)行單元,是系統(tǒng)獨(dú)立調(diào)度和分派cpu的基本單位及運(yùn)行中的程序的調(diào)度單位。
服務(wù)器啟動(dòng)后,可調(diào)用pthread_create函數(shù)創(chuàng)建第二線程,并將第二線程與第一線程關(guān)聯(lián),第二線程可專用于處理與第一線程相關(guān)的阻塞業(yè)務(wù)。阻塞是指調(diào)用結(jié)果返回之前,當(dāng)前線程會被掛起,即當(dāng)前線程進(jìn)入非可執(zhí)行狀態(tài),在這個(gè)狀態(tài)下,cpu不會給該線程分配時(shí)間片,該線程暫停運(yùn)行,函數(shù)只有在得到結(jié)果之后才會返回。阻塞業(yè)務(wù)即指會使當(dāng)前線程進(jìn)入阻塞狀態(tài)的客戶端請求。第二線程被創(chuàng)建后,可調(diào)用pthread_cond_wait函數(shù)先令第二線程進(jìn)入休眠狀態(tài),直至第一線程監(jiān)聽到有阻塞業(yè)務(wù)需要進(jìn)行處理時(shí),再喚醒第二線程,由第二線程進(jìn)行處理。將第二線程暫時(shí)休眠,等有阻塞業(yè)務(wù)需要處理時(shí)再喚醒,在第二線程的休眠期間節(jié)省了cpu的占用,節(jié)約了系統(tǒng)資源。
步驟s120,通過第一線程監(jiān)聽客戶端請求。
具體的,第一線程監(jiān)聽并處理由客戶端發(fā)送的客戶端請求。
步驟s130,通過第一線程判斷該客戶端請求是否為同步數(shù)據(jù)請求,若是,則執(zhí)行步驟s140,若否,則執(zhí)行步驟s150。
具體的,同步指的是在發(fā)出一個(gè)功能調(diào)用時(shí),在沒有得到結(jié)果之前,該調(diào)用就不返回,也就是必須一件一件事做,等前一件做完了才能做下一件事。同步數(shù)據(jù)請求即為該客戶端請求需要獲取同步數(shù)據(jù)才可進(jìn)行處理,例如需要到第三方的mysql(關(guān)系型數(shù)據(jù)庫管理系統(tǒng))服務(wù)器上請求相關(guān)數(shù)據(jù),因mysql服務(wù) 器只提供同步接口,若要訪問mysql的數(shù)據(jù),則必須等待直至數(shù)據(jù)從mysql返回,會造成線程阻塞,即該客戶端請求為阻塞業(yè)務(wù)。
步驟s140,通過第一線程喚醒第二線程,以使第二線程處理客戶端請求,并將處理結(jié)果返回客戶端。
具體的,當(dāng)?shù)谝痪€程監(jiān)聽到客戶端請求為同步數(shù)據(jù)請求時(shí),第一線程喚醒第二線程,由第二程處理該客戶端請求。第二線程根據(jù)該客戶端請求獲取同步數(shù)據(jù)進(jìn)行處理,并將最終處理結(jié)果返回客戶端。
步驟s150,通過第一線程處理該客戶端請求,并將處理結(jié)果返回客戶端。
具體的,若第一線程監(jiān)聽到的客戶端請求不是同步數(shù)據(jù)請求,則表示處理過程中不需要獲取同步數(shù)據(jù),即為非阻塞業(yè)務(wù),則由第一線程直接進(jìn)行處理,并將處理結(jié)果返回給客戶端。
上述線程調(diào)度方法,當(dāng)?shù)谝痪€程監(jiān)聽到同步數(shù)據(jù)請求,即當(dāng)?shù)谝痪€程監(jiān)聽到會造成線程阻塞的客戶端請求時(shí),喚醒第二線程,由第二線程處理該客戶端請求,可以有效區(qū)分阻塞型業(yè)務(wù)和非阻塞型業(yè)務(wù),進(jìn)而采用不同流程進(jìn)行處理,能夠在減少進(jìn)程運(yùn)行中線程切換帶來系統(tǒng)開銷的同時(shí)提高服務(wù)器處理客戶端請求的速度,有效提高客戶端的訪問速度,服務(wù)器對客戶端響應(yīng)快。
如圖2所示,在一個(gè)實(shí)施例中,步驟s140通過第一線程喚醒第二線程,以使第二線程處理客戶端請求,并將處理結(jié)果返回客戶端,具體包括以下步驟:
步驟s202,通過第一線程獲取與客戶端請求相關(guān)的數(shù)據(jù)。
具體的,當(dāng)客戶端請求為同步數(shù)據(jù)請求時(shí),第一線程需先獲取與該客戶端請求相關(guān)的數(shù)據(jù)。與客戶端請求相關(guān)的數(shù)據(jù)包括客戶端身份標(biāo)識、第一線程運(yùn)算結(jié)果及所需訪問的同步數(shù)據(jù)等,其中,第一線程運(yùn)算結(jié)果指的是第一線程在之前計(jì)算出的與該客戶端請求相關(guān)的運(yùn)算結(jié)果。
步驟s204,將與客戶端請求相關(guān)的數(shù)據(jù)存儲在預(yù)設(shè)的數(shù)據(jù)容器中。
具體的,服務(wù)器可預(yù)設(shè)一個(gè)數(shù)據(jù)容器用于存放與阻塞業(yè)務(wù)相關(guān)的數(shù)據(jù),當(dāng)?shù)谝痪€程監(jiān)聽到客戶端請求為同步數(shù)據(jù)請求時(shí),可將與該客戶端請求相關(guān)的數(shù)據(jù)存儲在預(yù)設(shè)的數(shù)據(jù)容器中,當(dāng)?shù)诙€程被喚醒后,即可從數(shù)據(jù)容器中讀取數(shù)據(jù)并進(jìn)行處理。在一個(gè)實(shí)施例中,步驟s204具體為將與客戶端請求相關(guān)的數(shù)據(jù) 按照預(yù)設(shè)的數(shù)據(jù)格式通過鏈表的形式存儲在預(yù)設(shè)的數(shù)據(jù)容器中,例如,預(yù)設(shè)的數(shù)據(jù)格式可包括三個(gè)內(nèi)容,內(nèi)容1為客戶端身份標(biāo)識,內(nèi)容2為第一線程運(yùn)算結(jié)果,內(nèi)容3為所需訪問的同步數(shù)據(jù),一個(gè)數(shù)據(jù)結(jié)構(gòu)表示一個(gè)任務(wù),并通過鏈表的形式進(jìn)行存儲??梢岳斫獾?,與客戶端請求的數(shù)據(jù)也可以其它的數(shù)據(jù)結(jié)構(gòu)進(jìn)行存儲。當(dāng)?shù)诙€程讀取數(shù)據(jù)容器中的數(shù)據(jù)時(shí),可按鏈表上的順序依次處理數(shù)據(jù)容器中的任務(wù)。
步驟s206,通過第一線程喚醒第二線程。
具體的,第一線程可通過調(diào)用pthread_cond_signal函數(shù)喚醒第二線程。
步驟s208,通過第二線程讀取數(shù)據(jù)容器的數(shù)據(jù),根據(jù)讀取的數(shù)據(jù)進(jìn)行相應(yīng)處理,并將處理結(jié)果返回客戶端。
具體的,第二線程被喚醒后,讀取數(shù)據(jù)容器中由第一線程存儲的數(shù)據(jù),并進(jìn)行解析,根據(jù)處理流程進(jìn)行處理,最后將處理結(jié)果返回客戶端。
如圖3所示,在一個(gè)實(shí)施例中,步驟s208通過第二線程讀取數(shù)據(jù)容器的數(shù)據(jù),根據(jù)讀取的數(shù)據(jù)進(jìn)行相應(yīng)處理,并將處理結(jié)果返回客戶端,具體包括:
步驟s302,通過第二線程讀取數(shù)據(jù)容器中的任務(wù)。
具體的,如圖4所示,數(shù)據(jù)容器中的數(shù)據(jù)通過鏈表的形式存儲,鏈表中的任務(wù)通過預(yù)設(shè)的數(shù)據(jù)結(jié)構(gòu)表示,數(shù)據(jù)結(jié)構(gòu)包括三個(gè)內(nèi)容,內(nèi)容1為客戶端身份標(biāo)識,內(nèi)容2為第一線程運(yùn)算結(jié)果,內(nèi)容3為所需訪問的同步數(shù)據(jù),每個(gè)任務(wù)代表一個(gè)需要獲取同步數(shù)據(jù)的客戶端請求。
步驟s304,使第二線程根據(jù)任務(wù)的所需訪問同步數(shù)據(jù)從第三方同步接口中獲取同步數(shù)據(jù)。
具體的,第二線程讀取數(shù)據(jù)容器中的任務(wù)并解析,可得到任務(wù)中數(shù)據(jù)結(jié)構(gòu)中的內(nèi)容。第二線程可先根據(jù)解析得到的所需訪問的同步數(shù)據(jù)通過第三方同步接口進(jìn)行訪問,并等待第三方將數(shù)據(jù)返回。例如,所需訪問的同步數(shù)據(jù)為uid(useridentification,用戶身份標(biāo)識)100的玩家現(xiàn)在金幣的具體數(shù)值,則第二線程向mysql服務(wù)器發(fā)送請求,并等待數(shù)據(jù)返回,獲取所需的同步數(shù)據(jù)。
步驟s306,使第二線程根據(jù)任務(wù)的第一線程運(yùn)算結(jié)果及同步數(shù)據(jù)進(jìn)行運(yùn)算。
具體的,第二線程獲取到所需的同步數(shù)據(jù)后,可根據(jù)解析得到的第一線程 運(yùn)算結(jié)果與同步數(shù)據(jù)一起進(jìn)行運(yùn)算,例如,第一線程運(yùn)算結(jié)果為uid100的玩家通過任務(wù)可獲得的金幣的具體數(shù)據(jù)為100金幣,同步數(shù)據(jù)為uid100的玩家當(dāng)前金幣的具體數(shù)據(jù)為1000金幣,通過運(yùn)算可得到uid100的玩家在任務(wù)完成后背包中的金幣的具體數(shù)值為1100金幣。
步驟s308,使第二線程根據(jù)任務(wù)的客戶端身份標(biāo)識將運(yùn)算結(jié)果返回給客戶端。
具體的,第二線程可根據(jù)解析得到的客戶端身份標(biāo)識將運(yùn)算結(jié)果返回給對應(yīng)的客戶端,返回成功后即表示該任務(wù)處理完成。
步驟s310,將從數(shù)據(jù)容器中讀取并處理的任務(wù)從數(shù)據(jù)容器中移除。
具體的,當(dāng)任務(wù)完成后,可將處理成功的任務(wù)從數(shù)據(jù)容器中移除,避免任務(wù)被重覆執(zhí)行處理。
步驟s312,通過第二線程判斷數(shù)據(jù)容器中是否還有未處理的任務(wù),若是,則執(zhí)行步驟s304,若否,則執(zhí)行步驟s314。
具體的,第二線程可查看數(shù)據(jù)容器中是否還有未處理的任務(wù),若是,則第二線程繼續(xù)讀取并處理數(shù)據(jù)容器中的任務(wù),直至數(shù)據(jù)容器中的任務(wù)量變?yōu)?,例如,如圖4中所示,在任務(wù)1后還有任務(wù)2,則第二線程處理完任務(wù)1后還需處理任務(wù)2,直至任務(wù)被全部處理完。若數(shù)據(jù)容器中沒有未處理的任務(wù),則可重新調(diào)用pthread_cond_wait函數(shù)使第二線程進(jìn)入休眠狀態(tài),等待下一次有阻塞業(yè)務(wù)需要處理時(shí)再被喚醒。
步驟s314,使第二線程進(jìn)入休眠狀態(tài)。
上述線程調(diào)度方法,當(dāng)?shù)谝痪€程監(jiān)聽到客戶端請求為同步數(shù)據(jù)請求時(shí),可將與該客戶端請求相關(guān)的數(shù)據(jù)存儲在數(shù)據(jù)容器中,并喚醒第二線程處理數(shù)據(jù)容器中的數(shù)據(jù),第一線程可繼續(xù)處理非阻塞業(yè)務(wù),由第二線程處理阻塞業(yè)務(wù),第一線程與第二線程互不影響,可以有效區(qū)分阻塞型業(yè)務(wù)和非阻塞型業(yè)務(wù),進(jìn)而采用不同流程進(jìn)行處理,能夠在減少進(jìn)程運(yùn)行中線程切換帶來系統(tǒng)開銷的同時(shí)提高服務(wù)器處理客戶端請求的速度,有效提高客戶端的訪問速度。
如圖5所示,一種線程調(diào)度裝置,包括啟動(dòng)模塊510、監(jiān)聽模塊520、判斷 模塊530、第一處理模塊540和第二處理模塊550。
啟動(dòng)模塊510,用于啟動(dòng)第一線程和第二線程,并使第二線程進(jìn)入休眠狀態(tài)。
具體的,進(jìn)程是程序的基本執(zhí)行實(shí)體,是指令、數(shù)據(jù)及其組織形式的描述,進(jìn)程是程序的實(shí)體。線程是程序中一個(gè)單一的順序控制流程,是進(jìn)程內(nèi)一個(gè)相對獨(dú)立的、可調(diào)度的執(zhí)行單元,是系統(tǒng)獨(dú)立調(diào)度和分派cpu的基本單位及運(yùn)行中的程序的調(diào)度單位。
服務(wù)器啟動(dòng)后,可調(diào)用pthread_create函數(shù)創(chuàng)建第二線程,并將第二線程與第一線程關(guān)聯(lián),第二線程可專用于處理與第一線程相關(guān)的阻塞業(yè)務(wù)。阻塞是指調(diào)用結(jié)果返回之前,當(dāng)前線程會被掛起,即當(dāng)前線程進(jìn)入非可執(zhí)行狀態(tài),在這個(gè)狀態(tài)下,cpu不會給該線程分配時(shí)間片,該線程暫停運(yùn)行,函數(shù)只有在得到結(jié)果之后才會返回。阻塞業(yè)務(wù)即指會使當(dāng)前線程進(jìn)入阻塞狀態(tài)的客戶端請求。第二線程被創(chuàng)建后,可調(diào)用pthread_cond_wait函數(shù)先令第二線程進(jìn)入休眠狀態(tài),直至第一線程監(jiān)聽到有阻塞業(yè)務(wù)需要進(jìn)行處理時(shí),再喚醒第二線程,由第二線程進(jìn)行處理。將第二線程暫時(shí)休眠,等有阻塞業(yè)務(wù)需要處理時(shí)再喚醒,在第二線程的休眠期間節(jié)省了cpu的占用,節(jié)約了系統(tǒng)資源。
監(jiān)聽模塊520,用于通過第一線程監(jiān)聽客戶端請求。
具體的,第一線程監(jiān)聽并處理由客戶端發(fā)送的客戶端請求。
判斷模塊530,用于通過第一線程判斷客戶端請求是否為同步數(shù)據(jù)請求。
具體的,同步指的是在發(fā)出一個(gè)功能調(diào)用時(shí),在沒有得到結(jié)果之前,該調(diào)用就不返回,也就是必須一件一件事做,等前一件做完了才能做下一件事。同步數(shù)據(jù)請求即為該客戶端請求需要獲取同步數(shù)據(jù)才可進(jìn)行處理,例如需要到第三方的mysql服務(wù)器上請求相關(guān)數(shù)據(jù),因mysql服務(wù)器只提供同步接口,若要訪問mysql的數(shù)據(jù),則必須等待直至數(shù)據(jù)從mysql返回,會造成線程阻塞,即該客戶端請求為阻塞業(yè)務(wù)。
第一處理模塊540,用于當(dāng)?shù)谝痪€程判斷出客戶端請求不是同步數(shù)據(jù)請求時(shí),則通過第一線程處理客戶端請求,并將處理結(jié)果返回客戶端。
具體的,若第一線程監(jiān)聽到的客戶端請求不是同步數(shù)據(jù)請求,則表示處理過程中不需要獲取同步數(shù)據(jù),即為非阻塞業(yè)務(wù),則由第一線程直接進(jìn)行處理, 并將處理結(jié)果返回給客戶端。
第二處理模塊550,用于當(dāng)?shù)谝痪€程判斷出客戶端請求是同步數(shù)據(jù)請求時(shí),則通過第一線程喚醒第二線程,以使第二線程處理該客戶端請求,并將處理結(jié)果返回客戶端。
具體的,當(dāng)?shù)谝痪€程監(jiān)聽到客戶端請求為同步數(shù)據(jù)請求時(shí),第一線程喚醒第二線程,由第二程處理該客戶端請求。第二線程根據(jù)該客戶端請求獲取同步數(shù)據(jù)進(jìn)行處理,并將最終處理結(jié)果返回客戶端。
上述線程調(diào)度裝置,當(dāng)?shù)谝痪€程監(jiān)聽到同步數(shù)據(jù)請求,即當(dāng)?shù)谝痪€程監(jiān)聽到會造成線程阻塞的客戶端請求時(shí),喚醒第二線程,由第二線程處理該客戶端請求,可以有效區(qū)分阻塞型業(yè)務(wù)和非阻塞型業(yè)務(wù),進(jìn)而采用不同流程進(jìn)行處理,能夠在減少進(jìn)程運(yùn)行中線程切換帶來系統(tǒng)開銷的同時(shí)提高服務(wù)器處理客戶端請求的速度,有效提高客戶端的訪問速度,服務(wù)器對客戶端響應(yīng)快。
如圖6所示,在一個(gè)實(shí)施例中,上述線程調(diào)度裝置,第二處理模塊550包括獲取單元552、存儲單元554、喚醒單元556、處理單元558。
獲取單元552,用于通過第一線程獲取與客戶端請求相關(guān)的數(shù)據(jù)。
具體的,當(dāng)客戶端請求為同步數(shù)據(jù)請求時(shí),第一線程需先獲取與該客戶端請求相關(guān)的數(shù)據(jù)。與客戶端請求相關(guān)的數(shù)據(jù)包括客戶端身份標(biāo)識、第一線程運(yùn)算結(jié)果及所需訪問的同步數(shù)據(jù)等,其中,第一線程運(yùn)算結(jié)果指的是第一線程在之前計(jì)算出的與該客戶端請求相關(guān)的運(yùn)算結(jié)果。
存儲單元554,用于將與客戶端請求相關(guān)的數(shù)據(jù)存儲在預(yù)設(shè)的數(shù)據(jù)容器中。
具體的,服務(wù)器可預(yù)設(shè)一個(gè)數(shù)據(jù)容器用于存放與阻塞業(yè)務(wù)相關(guān)的數(shù)據(jù),當(dāng)?shù)谝痪€程監(jiān)聽到客戶端請求為同步數(shù)據(jù)請求時(shí),可將與該客戶端請求相關(guān)的數(shù)據(jù)存儲在預(yù)設(shè)的數(shù)據(jù)容器中,當(dāng)?shù)诙€程被喚醒后,即可從數(shù)據(jù)容器中讀取數(shù)據(jù)并進(jìn)行處理。在一個(gè)實(shí)施例中,存儲單元554還用于將與客戶端請求相關(guān)的數(shù)據(jù)按照預(yù)設(shè)的數(shù)據(jù)格式通過鏈表的形式存儲在預(yù)設(shè)的數(shù)據(jù)容器中。例如,預(yù)設(shè)的數(shù)據(jù)格式可包括三個(gè)內(nèi)容,內(nèi)容1為客戶端身份標(biāo)識,內(nèi)容2為第一線程運(yùn)算結(jié)果,內(nèi)容3為所需訪問的同步數(shù)據(jù),一個(gè)數(shù)據(jù)結(jié)構(gòu)表示一個(gè)任務(wù),并通過鏈表的形式進(jìn)行存儲??梢岳斫獾兀c客戶端請求的數(shù)據(jù)也可以其它的數(shù)據(jù) 結(jié)構(gòu)進(jìn)行存儲。當(dāng)?shù)诙€程讀取數(shù)據(jù)容器中的數(shù)據(jù)時(shí),可按鏈表上的順序依次處理數(shù)據(jù)容器中的任務(wù)。
喚醒單元556,用于通過第一線程喚醒第二線程。
具體的,第一線程可通過調(diào)用pthread_cond_signal函數(shù)喚醒第二線程。
處理單元558,用于通過第二線程讀取數(shù)據(jù)容器的數(shù)據(jù),根據(jù)讀取的數(shù)據(jù)進(jìn)行相應(yīng)處理,并將處理結(jié)果返回客戶端。
具體的,第二線程被喚醒后,讀取數(shù)據(jù)容器中由第一線程存儲的數(shù)據(jù),并進(jìn)行解析,根據(jù)處理流程進(jìn)行處理,最后將處理結(jié)果返回客戶端。
如圖7所示,在一個(gè)實(shí)施例中,處理單元558包括讀取子單元802、獲取子單元804、運(yùn)算子單元806、返回子單元808、移除子單元810和判斷子單元812。
讀取子單元802,用于通過第二線程讀取數(shù)據(jù)容器中的任務(wù),任務(wù)通過預(yù)設(shè)的數(shù)據(jù)格式表示。
具體的,如圖4所示,數(shù)據(jù)容器中的數(shù)據(jù)通過鏈表的形式存儲,鏈表中的任務(wù)通過預(yù)設(shè)的數(shù)據(jù)結(jié)構(gòu)表示,數(shù)據(jù)結(jié)構(gòu)包括三個(gè)內(nèi)容,內(nèi)容1為客戶端身份標(biāo)識,內(nèi)容2為第一線程運(yùn)算結(jié)果,內(nèi)容3為所需訪問的同步數(shù)據(jù),每個(gè)任務(wù)代表一個(gè)需要獲取同步數(shù)據(jù)的客戶端請求。
獲取子單元804,用于使第二線程根據(jù)任務(wù)的所需訪問的同步數(shù)據(jù)從第三方同步接口中獲取同步數(shù)據(jù)。
具體的,第二線程讀取數(shù)據(jù)容器中的任務(wù)并解析,可得到任務(wù)中數(shù)據(jù)結(jié)構(gòu)中的內(nèi)容。第二線程可先根據(jù)解析得到的所需訪問的同步數(shù)據(jù)通過第三方同步接口進(jìn)行訪問,并等待第三方將數(shù)據(jù)返回。例如,所需訪問的同步數(shù)據(jù)為uid100的玩家現(xiàn)在金幣的具體數(shù)值,則第二線程向mysql服務(wù)器發(fā)送請求,并等待數(shù)據(jù)返回,獲取所需的同步數(shù)據(jù)。
運(yùn)算子單元806,用于使第二線程根據(jù)任務(wù)的第一線程運(yùn)算結(jié)果及同步數(shù)據(jù)進(jìn)行運(yùn)算。
具體的,第二線程獲取到所需的同步數(shù)據(jù)后,可根據(jù)解析得到的第一線程運(yùn)算結(jié)果與同步數(shù)據(jù)一起進(jìn)行運(yùn)算,例如,第一線程運(yùn)算結(jié)果為uid100的玩家通過任務(wù)可獲得的金幣的具體數(shù)據(jù)為100金幣,同步數(shù)據(jù)為uid100的玩家當(dāng)前 金幣的具體數(shù)據(jù)為1000金幣,通過運(yùn)算可得到uid100的玩家在任務(wù)完成后背包中的金幣的具體數(shù)值為1100金幣。
返回子單元808,用于使第二線程根據(jù)任務(wù)的客戶端身份標(biāo)識將運(yùn)算結(jié)果返回給客戶端。
具體的,第二線程可根據(jù)解析得到的客戶端身份標(biāo)識將運(yùn)算結(jié)果返回給對應(yīng)的客戶端,返回成功后即表示該任務(wù)處理完成。
移除子單元810,用于將從數(shù)據(jù)容器中讀取并處理的任務(wù)從數(shù)據(jù)容器中移除。
具體的,當(dāng)任務(wù)完成后,可將處理成功的任務(wù)從數(shù)據(jù)容器中移除,避免任務(wù)被重覆執(zhí)行處理。
判斷子單元812,用于通過第二線程判斷數(shù)據(jù)容器中是否還有未處理的任務(wù),若是,則使第二線程繼續(xù)讀取數(shù)據(jù)容器中的任務(wù)并處理,若否,則使第二線程進(jìn)入休眠狀態(tài)。
具體的,第二線程可查看數(shù)據(jù)容器中是否還有未處理的任務(wù),若是,則第二線程繼續(xù)讀取并處理數(shù)據(jù)容器中的任務(wù),直至數(shù)據(jù)容器中的任務(wù)量變?yōu)?,例如,如圖4中所示,在任務(wù)1后還有任務(wù)2,則第二線程處理完任務(wù)1后還需處理任務(wù)2,直至任務(wù)被全部處理完。若數(shù)據(jù)容器中沒有未處理的任務(wù),則可重新調(diào)用pthread_cond_wait函數(shù)使第二線程進(jìn)入休眠狀態(tài),等待下一次有阻塞業(yè)務(wù)需要處理時(shí)再被喚醒。
上述線程調(diào)度裝置,當(dāng)?shù)谝痪€程監(jiān)聽到客戶端請求為同步數(shù)據(jù)請求時(shí),可將與該客戶端請求相關(guān)的數(shù)據(jù)存儲在數(shù)據(jù)容器中,并喚醒第二線程處理數(shù)據(jù)容器中的數(shù)據(jù),第一線程可繼續(xù)處理非阻塞業(yè)務(wù),由第二線程處理阻塞業(yè)務(wù),第一線程與第二線程互不影響,可以有效區(qū)分阻塞型業(yè)務(wù)和非阻塞型業(yè)務(wù),進(jìn)而采用不同流程進(jìn)行處理,能夠在減少進(jìn)程運(yùn)行中線程切換帶來系統(tǒng)開銷的同時(shí)提高服務(wù)器處理客戶端請求的速度,有效提高客戶端的訪問速度。
以上所述實(shí)施例的各技術(shù)特征可以進(jìn)行任意的組合,為使描述簡潔,未對上述實(shí)施例中的各個(gè)技術(shù)特征所有可能的組合都進(jìn)行描述,然而,只要這些技 術(shù)特征的組合不存在矛盾,都應(yīng)當(dāng)認(rèn)為是本說明書記載的范圍。
以上所述實(shí)施例僅表達(dá)了本發(fā)明的幾種實(shí)施方式,其描述較為具體和詳細(xì),但并不能因此而理解為對發(fā)明專利范圍的限制。應(yīng)當(dāng)指出的是,對于本領(lǐng)域的普通技術(shù)人員來說,在不脫離本發(fā)明構(gòu)思的前提下,還可以做出若干變形和改進(jìn),這些都屬于本發(fā)明的保護(hù)范圍。因此,本發(fā)明專利的保護(hù)范圍應(yīng)以所附權(quán)利要求為準(zhǔn)。