久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

天涯明月刀-無棧協(xié)程的應用

 鳳凰苑兇真 2017-10-13

一、協(xié)程介紹

協(xié)程是一種用戶級輕量線程,,不僅擁有自己的寄存器上下文和棧,,而且可以由用戶自主調(diào)度執(zhí)行,我們可以在一個線程里面輕松創(chuàng)建數(shù)十萬個協(xié)程,,就像數(shù)十萬次普通函數(shù)調(diào)用一樣輕松,。相對于普通函數(shù)只有一次進出,協(xié)程可以有多次進出的能力,,它通過將函數(shù)上下文數(shù)據(jù)(主要指寄存器和函數(shù)棧)保存起來,,在特定的時刻恢復回去繼續(xù)執(zhí)行來實現(xiàn)的,。在linux里,可以通過getcontext和swapcontext等接口來實現(xiàn)協(xié)程,。

下面展示了一個典型協(xié)程應用的場景,,某個功能分為3個步驟,分布在兩個進程A,、B上,,A執(zhí)行步驟1,需要向B發(fā)出消息完成步驟2,,等待返回后完成步驟3:

 

可以看到協(xié)程擁有將一個異步過程轉(zhuǎn)化為同步過程的非凡能力,,大大減輕了我們的開發(fā)工作量。

協(xié)程主要分為對稱式(symmetric),、非對稱(asymmetric)式兩種(參見boost協(xié)程庫),,兩者的主要區(qū)別在于:

1、對稱協(xié)程只提供一種傳遞操作,,用于在協(xié)程間直接傳遞控制,,協(xié)程每次需要掛起時需要指定一個明確切換的目標協(xié)程,也就是說控制權(quán)只能在協(xié)程間跳轉(zhuǎn),。

2,、非對稱協(xié)程提供調(diào)用和掛起兩種操作,掛起時控制權(quán)返回給調(diào)用者,。被調(diào)用的協(xié)程可以看成時從屬于調(diào)用者,,這種協(xié)程在日常使用中更常見,上文的例子就屬于非對稱式,。

二,、協(xié)程在游戲中的應用

      游戲服務端往往會按照業(yè)務特點拆分成多種角色,例如天涯明月刀服務器主要包含:world(負責玩家登錄,、場景管理等),、scene(場景服務器)、social(幫派),、home(家園),、auction(拍賣)等。玩家從一個場景跳轉(zhuǎn)到另外一個場景,,牽涉到world和scene兩種角色的服務器,,主要包括創(chuàng)建新場景、離開舊場景,、進入新場景,、舊場景的銷毀四個異步操作,狀態(tài)轉(zhuǎn)換如下:

 兩個狀態(tài)機定義代碼如下:

     我們可以看到場景跳轉(zhuǎn)過程中的每一個異步操作都帶來了一個中間狀態(tài),,比如創(chuàng)建新場景帶來了actor_in_waitlist狀態(tài),、離開舊場景帶來了actor_wait_leave_old狀態(tài),。這么多的中間狀態(tài)不僅帶來了開發(fā)上的難度,而且使項目的維護成本極高,,使用協(xié)程對跳轉(zhuǎn)過程中的中間狀態(tài)進行收斂就顯得格外有必要,。

     將這四個異步操作歸并到一個協(xié)程trans中,如下所示:

  最終玩家和場景的眾多狀態(tài)得到了有效的收斂,,結(jié)果如下:



三,、天涯明月刀協(xié)程應用存在的問題

天涯明月刀服務器通過共享內(nèi)存實現(xiàn)了一種resume的機制,將狀態(tài)數(shù)據(jù)存放在共享內(nèi)存中,,游戲進程crash后再次重啟attach原共享內(nèi)存,,所有狀態(tài)得到恢復,玩家不受影響,。resume機制使游戲容災能力得到很大程度的提升,,但同時也讓上文所述的普通協(xié)程失去了作用,主要有以下兩點原因:

(1)resume后?;刂?、堆基地址等發(fā)生了變化,寄存器上下文中保存的地址將會失效,;

(2)協(xié)程棧內(nèi)用戶使用的指針也將失效,;

如果我們切換時不保存函數(shù)的上下文(寄存器上下文和棧),僅記錄函數(shù)的執(zhí)行位置,,并作為函數(shù)的一個參數(shù)傳遞,,函數(shù)每次調(diào)用時根據(jù)這個參數(shù)直接跳到相應的位置執(zhí)行,函數(shù)的位置作為一個值記錄在共享內(nèi)存中,,這樣自然的解決了普通協(xié)程失效的問題,?;谶@種思路,,利用switch case實現(xiàn)了一種無棧協(xié)程的方案,成功模擬了普通協(xié)程的語義,,取得了很好的應用效果,。

      我們首先來看一下一個叫達夫設備(Duff's Device)的代碼:

voidsend_duff(char *to, char *from, int count)

{

        int n = (count 7) / 8;

        switch(count% 8) {

        case0: do {    *to = *from ;

        case7:         *to = *from ;

        case6:         *to = *from ;

        case5:         *to = *from ;

        case4:         *to = *from ;

        case3:         *to = *from ;

        case2:         *to = *from ;

        case1:         *to = *from ;

                }while(--n > 0);

        }

}

代碼的結(jié)構(gòu)顯得非常巧妙,把一個switch語句和一個do-while語句糅合在了一起,。程序的執(zhí)行流程是:程序一開始順序執(zhí)行,,當它執(zhí)行到了switch的時候,就會根據(jù)n的值,,直接跳轉(zhuǎn)到 case n那里,,程序繼續(xù)順序執(zhí)行,當它執(zhí)行到while那里時,,就會判斷循環(huán)條件,。若為真,,則while循環(huán)開始,程序跳轉(zhuǎn)到do那里開始執(zhí)行循環(huán),;為假,,則退出循環(huán),即程序中止,。

這段代碼的本意是為了提高執(zhí)行的效率(一次比較能帶來多個賦值),,但是我們在這主要關(guān)注它的奇特語法,可以看到switch case分支可以滲透到代碼中的任意地方,,如果能在我們需要異步處理的地方加上case分支后離開,,異步處理回來后可以利用switch直接跳轉(zhuǎn)到case分支處繼續(xù)往下執(zhí)行,從而模擬了普通協(xié)程的yield語義,。

利用 swich case對普通函數(shù)進行改造,,使其成為一個協(xié)程,改造過程如下:

    


改造完的代碼比較奇特,,建議將代碼實際運行一遍,,可以跟蹤到在step1后flag設置為1后函數(shù)退出,切換回來后跳過step1后執(zhí)行step2,,達到了我們需要的效果,。

閱讀上面的代碼馬上可以發(fā)現(xiàn)它的一個致命缺點:可讀性太差、不便于理解維護,。是否可以利用宏定義來簡化上面的代碼,,其中(1)定義如下:



  (2),、(3)定義如下:


  


  經(jīng)簡化后協(xié)程代碼如下:


 


  CORO_YIELD_IMPL中需要傳入1,、2等位置參數(shù),這種參數(shù)對協(xié)程實際使用者沒有任何作用,,反而增加了理解負擔,,可以利用編譯器計數(shù)器__COUNTER__自動設置位置參數(shù):


 


  至此,一個通用的無棧協(xié)程基本實現(xiàn),,我們只要對函數(shù)增加一個位置參數(shù)并默認為0,,即可將其改造為一個協(xié)程,最終一個協(xié)程如下:


  


  只要將coro_data保存起來,,隨時都可以再次恢復現(xiàn)場,,做到了使異步操作同步化,降低了異步開發(fā)的復雜性,、提高了代碼的可維護性,。在天刀的實際應用中根據(jù)應用場景還會對上述無棧協(xié)程進一步封裝,實現(xiàn)了一個協(xié)程管理器,,實現(xiàn)了更多的功能,,這個以后有機會還會談到,。


四、總結(jié)

  上文所述的無棧協(xié)程成功的解決了普通有棧協(xié)程在resume失效的問題,,同有棧協(xié)程相比,,優(yōu)點:

   1、切換時,,不涉及內(nèi)核態(tài)切換,,類似于普通函數(shù)調(diào)用效率更高。

   2,、不用考慮有棧協(xié)程中的由于棧開辟空間太小導致的棧溢出的問題,。

   3、代碼小巧,,跨平臺,。

   缺點:

   由于其不保存上下文,函數(shù)棧內(nèi)的零時變量都不會保存,,只能依賴傳遞的參數(shù)再次恢復數(shù)據(jù),。  

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點,。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,,謹防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報,。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多