1. 程式人生 > >Python遊戲伺服器開發日記(五)skynet_messagequeue和skynet_timer

Python遊戲伺服器開發日記(五)skynet_messagequeue和skynet_timer

        最近,skynet群裡有同好與我一起討論skynet底層一些比較難理解的實現細節,乘此機會仔細看了一下原始碼,我最關心的是skynet_mq和skynet_timer兩個我會用到的部分。


        本文不想討論太細節的問題,具體的實現思路我並沒有理的非常清晰,還是看程式碼為好。我這裡從實際需求出發,寫一些tips,方便新來的小夥伴參考。


        skynet的timer和mq,解耦做的非常好,寫一個test.c,將它們單獨編譯,即可單獨測試這兩個模組,呼叫標頭檔案裡提供的api,可以加深理解。我是直接把它們放到了我的工程裡:)


------------ skynet_timer ---------------
        skynet的timer,是單獨啟動了一個執行緒,不斷的呼叫tick,檢查下一個需要被觸發的timer。
        timer的結構體,包含一個near陣列和t[4]二維陣列,要注意他倆的長度也不一樣。。。處理的時候比較繁雜。
        分成near和t兩個陣列,其實是為了優化。系統time是毫秒級的,每個node裡儲存的都是絕對時間,根據絕對時間離現在的遠近,放在不同的數組裡。
        每次只需要查詢near裡的timer,比較快速。
        判斷時間遠近的演算法都是借用位運算,符合雲風的風格。對C的二進位制操作不熟悉的朋友,可能會略難懂。
        
        明白了以上幾點,如果看清了timer每個函式的意思,還是比較好理解的。剩下一個難點就是時間的迴繞問題。
        迴繞的原因是用毫秒級計數器儲存時間,int32只能儲存幾十天的長度,計數器必然會在伺服器工作時從0xffffffff回到0,skynet_timer的處理比較奇葩,在add_node的時候,沒有做任何特殊處理,導致糊里糊塗的把node加入了佇列。
        分析的關鍵一點就破——所有可能迴繞的node(時間不要過於太遠的),都被陰差陽錯的放在了t[3][0]裡面。
        然後檢測到當前時間點回繞的時候,只要把t[3][0]裡的node全都拿出來重新插入一遍即可。這個方法比較trick,反正結果正確就行。


------------- skynet_mq -----------------
        skynet的message_queue,是global_queue和service私有queue的結合體。


        有了service私有queue,每個service同時就只能處理一個訊息!這是重點,這是天然的鎖,在整個架構中,其實這是一個重點。
        它保證了同一個service不會出現併發。
        還是強調一下上面這點,我設計自己的系統時老忘 :)


        global_queue是掛了一串mq,service處理訊息時,把自己的mq取下來,處理完再掛回去。可以避免鎖的使用。
        其實後來,global_queue的處理還是加上了鎖(貌似叫自旋鎖?),因為其實skynet較早的完全無鎖實現,並不能通過某些仔細設計的單元測試(這一點我是從github的上傳記錄裡看到的)。問了雲風本人,雲大表示至少現在的邏輯更清晰了。


------------ 理解context和session -----------
        context 是service執行內容的上下文,貌似一個service只有一個context。
        session是一個整數,用於管理coroutine。lua的coroutine本人非常不熟,這塊也無法借鑑。好在python的greenlet我認為更方便使用,greenlet的 C API 也很清晰,很容易和messagequeue嵌入到一起。
        每個context或者說每個service,每當呼叫skynet.call或者skynet.sleep等導致掛起的函式時,都會產生一個coroutine,分配一個新的session號(簡單+1即可),等callback的時候,用這個session號找回原來的coroutine繼續執行。
        (這塊留空,我還要再仔細確認一下,繼續完善)

相關推薦

Python遊戲伺服器開發日記skynet_messagequeueskynet_timer

        最近,skynet群裡有同好與我一起討論skynet底層一些比較難理解的實現細節,乘此機會仔細看了一下原始碼,我最關心的是skynet_mq和skynet_timer兩個我會用到的部分。         本文不想討論太細節的問題,具體的實現思路我並沒有理的非

LayIM.AspNetCore Middleware 開發日記Init接口實現細節

nco 記得 結果 主界面 群組 ont 轉發器 取出 ima 前言   “一旦開始了就要堅持下去“。為什麽本文的第一句話是這麽一句話呢,因為我經常就是開頭轟轟烈烈,結果越來越枯燥,就不想做下去了。但是版圖就放棄又那麽不甘心,繼續加油吧。   吐槽完畢,進入正題。在上一篇中

python學習日記

        不好意思,這次拖更了這麼久,實在是事情纏身,鍋從天上來emmm。好在現在緊急的事情沒有了,剩下的就慢慢做吧,學習依然得繼續了。         今天學的主要是迴圈和分支。老用while肯定是不行的,像

Unity3D獨立遊戲開發日記:擺放建築物

在沙盒遊戲裡,能自由建造是很重要的特點,比如說風靡全球的《我的世界》,用一個個方塊就能搭建出規模巨集大的世界。甚至有偏激的人說,沒有自由建造,就不是一個真正的沙盒遊戲。的確,沙盒遊戲的魅力有很大一部分是能自由構建一個遊戲世界。看著自己一磚一瓦搭建起一個城堡世界會很有成就感的。 現如今的手遊,大多數就是一個爭

遊戲開發筆記——服務端系統分層

        本來很想按順序寫下來,到了第五篇是打算先寫架構的,無奈這東西暫時沒辦法弄的比較通透,拖了很久也還是覺得寫起來有困難。有一個客觀因素是這陣子有點忙,很多東西要做,也沒辦法留出許多時間用來學習。         還是先寫已經有點概念的東西吧.... 關於架構:

我的遊戲開發筆記:Animator的運用二

好了好了,上篇說到如何用程式碼來控制Animator裡的條件引數,話不多說,直接開始。 Animator m_Animator;m_Animator = GetComponent<Animator>(); m_Animator.SetBool("OnGround

微信公眾平臺開發教程自定義菜單

打開鏈接 delete toolbar 推送 優化 pcl reader 接口查詢 robot 應大家強烈要求,將自定義菜單功能課程提前。 一、概述: 如果只有輸入框,可能太簡單,感覺像命令行。自定義菜單,給我們提供了很大的靈活性,更符合用戶的操作習慣。在一個小小的微信對話

Python進階內容--- typeobject的關系

行動 關系 函數 tex 進階 類模板 clas lin cnblogs 面向對象編程(OOP)的兩大關系 繼承與實現 繼承關系: 子類繼承自父類(base),可以使用父類的一些方法(method)和屬性(attribute) 實現關系: 以類為模板,實例化一個對

運維學python之爬蟲中級篇數據存儲無數據庫版

就是 erro mage name 打印 反序 lis object Circul 本篇主要介紹,爬取html數據後,將html的正文內容存儲為json或csv格式。 1 json格式存儲 選定要爬取的網站後,我們利用之前學過的內容,如:Beautiful Soup、xpa

Python網絡爬蟲筆記:下載、分析京東P20銷售數據

9.png amp F12 不存在 strong xls sco 列表 std (一) 分析網頁 下載下面這個鏈接的銷售數據 https://item.jd.com/6733026.html#comment 1、 翻頁的時候,谷歌F12的Network頁簽可以

Python+OpenCV圖像處理—— ROI與泛洪填充

targe ros com ray inter color 方式 高度 lan 一、ROI ROI(region of interest),感興趣區域。機器視覺、圖像處理中,從被處理的圖像以方框、圓、橢圓、不規則多邊形等方式勾勒出需要處理的區域,稱為感興趣區域,ROI。

LayIM.AspNetCore Middleware 開發日記閑言碎語

時光 運行 過時 del middle 一個 例如 nbsp target 前言   前幾天寫博客的時候突然看見了歷史上的今天。不禁感慨時光如梭,這系列博客後來被我標註了已經過時,但是還有很多小夥伴咨詢我。既然過時就要更新,正好 .NET Core 也出來很久了,於是乎想

LayIM.AspNetCore Middleware 開發日記預備知識介紹

Locator route ppk 我只 netcore blank req rop read 前言   開發一個AspNetCore的中間件需要理解RequestDelegate。另外,還需要理解.NET Core中的依賴註入。還有一個就是內嵌資源的訪問。例如:Embed

LayIM.AspNetCore Middleware 開發日記主角登場LayIM介紹

融雲 文檔 應該 步驟 end 想要 .sql 味道 asp.net 前言   在前幾篇中已經初步介紹了開發AspNetCore中間件的一些基礎知識,不過都沒有很深入的去研究,後續還是需要去看看源碼。本篇呢,終於有點開頭的味道了,就是要介紹LayIM了,其實標題寫的是主角,

Salesforce 開發整理代碼開發最佳實踐

pdf fir 應該 hid lang perf PE pan 單詞   在Salesforce項目實施過程中,對項目代碼的維護可以說占據極大的精力,無論是因為項目的叠代,還是需求的變更,甚至是項目組成員的變動,都不可避免的需要維護之前的老代碼,而事實上,幾乎沒有任何一個項

Python基礎班每日整理

承擔 類的屬性 設計 orien 字符 day01 列表 核心 python 03_面向對象_day01 面向對象的簡稱?面向對象編程 —— Object Oriented Programming 簡寫 OOP,是一種編程思想或者方式 面向對象和面向過程的區別?面向過程是

3ds Max學習日記

人物 對稱 itl 想要 .net tle 學習日記 分享圖片 cage ??把實驗室要用的小工具做了出來後,忙裏偷閑,把第四章沒看完的視頻看完了。修改器(modifier)什麽的還是挺好玩的。 ??FFD,車削,倒角,倒角剖面,對稱,擠出,晶格,扭曲,融化,彎曲,網格平滑

Git工程開發實踐——Git分布式工作流程

項目 廣泛 小團隊 不常用 工作 forward 存在 proc http Git工程開發實踐(五)——Git分布式工作流程 一、Git分布式工作流程簡介 與集中式版本控制系統(CVCS)不同,Git的分布式特性使得開發者間的協作變得更加靈活多樣。在集中式系統中,每個開發者

LayIM.AspNetCore Middleware 開發日記Asp.Net.Core.SignalR閃亮登場

you socket https image upm ogg 通訊 () aspnet 前言 ??前幾篇介紹了整個中間件的構成,路由,基本配置等等.基本上沒有涉及到通訊部分。不過已經實現了融雲的通訊功能,由於是第三方的就不在單獨去寫。正好.NET Core SignalR已

Android 開發初識ListView(列表佈局)

效果: xml: <ListView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/li