ProudNet 實用程式
使用收藏
STL、ATL等也已經提供收藏類(std.map, std.vector, CFastArray, CAtlArray, CAtlMap等)。 但是ProudNet在STL和ATL都難以使用的情況下,或在要求高速性能的情況下提供有效的類
類別 | 函數 | 註釋 |
---|---|---|
數組類 | Proud.CFastArray | 內部使用 Fast heap 。 |
鏈接列表類 | Proud.CFastList | 內部使用Fast Heap。 與CFastArray不同,該類可以與創建者、消失者和輻射分配操作員一起使用。 |
地圖類 | Proud.CFastMap | (Key, Value) 使用成對的哈希算法。 與CAtlMap的使用方法非常相似,STL.map的重複序列和一些方法可以相同地使用。 |
設定類 | Proud.CFastSet | 與CFastMap不同,Key是僅有的類,其餘與CFastMap相同。 |
快速內存管理器
ProudNet內置高性能內存管理器,開發者可以利用高性能內存管理器加速應用程序的加工性能。
ProudNet支持的存儲管理器大致如下。
- Lookaside allocator
Lookaside allocator應用了通常的memory pool技術。 如果您必須經常分配/ 釋放相同大小的內存, 推薦使用 Lookaside allocator 。
主要機制如下。
分配新的存儲塊時,分配新的系統內存。
當解鎖存儲塊時,解鎖的塊將返回至lookaside allocator。
重新分配存儲塊時,返還給lookaside allocator的存儲塊將被再利用。
這個過程以非常快的速度運行。 比OS環境下的內存分配速度要快得多。
但也存在缺點。
Lookaside allocator總是隻能分配大小相同的內存。
分配給 Lookaside allocator 的內存塊必須在 Lookaside allocator 被破壞之前全部釋放。
使用Lookaside allocator的方法如下。
首先使用 Proud.CLookasideAllocator.New 方法創建對象。 創建全局對象也可以。
將存儲塊分配給 Proud.CLookasideAllocator.Alloc 方法。
解除設置爲 Proud.CLookasideAllocator.Free。 Realloc不存在。
解除所有存儲塊後,破壞 Proud.CLookasideAllocator 對象。
- Fast Heap
ProudNet的Fast heap雖然比Lookaside allocator稍微慢一些,但是比OS環境下的存儲器分配/解除速度更快,可以分配/解除各種大小的存儲器塊。
ProudNet 的 Fastheap 的實現類是 Proud.CFastHeap。 Proud.CFastHeap 還可以在所有存儲塊被破壞後移除 Proud.CFastHeap 對象。
Fast heap的使用方法如下。
首先以Proud.CFastHeap.New方法生成Fast heap對象。 創建全局對象也可以。
用 Proud.CFastHeap.Alloc 方法分配內存塊 。
解除爲Proud.CFastHeap.Free。 可用CFastHeap.Realloc重新分配內存塊。
解除所有存儲塊後,破壞 Proud.CFastHeap 對象。
指定為 C++ 類別的預設分配器
在C++類中容易接受Fast heap或Lookaside allocator的加速的方法是覆蓋C++的operator new, delete方法。
這樣,在創建和破壞C++類作爲new、delete操作符時,將使用Fast heap或Lookaside allocator代替系統的內存heap。
在以下示例中,當將類實例化到 operator new 或 delete 時,高性能內存管理器將允許您分配/ 釋放內存。 它們各有優缺點,請適當選擇使用。
智能指示器
ProudNet擁有智能指針Proud.RefCount類。
智能指針是指,只要存在參照生成客體的變數,就能起到保障該客體的存在本身的作用。 而且,只有當參照該客體的變數不再存在時,該客體纔會被破壞。
它還可以解決由於開發人員創建的錯誤(dangling)而引用已被銷毀的物件的問題或未銷毀物件的問題(leak)。
智能指針變量每次複製時客體參考計數增加1,下圖中Object Instance一直存在到參考計數爲0。
有時候想在多處參照客體的智能指示器的狀態下強制破壞客體。
例如,如果智能指示器參考擁有打開文件手柄的對象,則有時需要立即破壞擁有文件手柄的對象。
但如果智能指示器到處參照客體,就無法知道客體被破壞的時間,因此可能會遇到難關。 在這種情況下,可以使用Dispose Pattern明確執行多處參考對象的破壞。
- Dispose Pattern
Dispose Pattern是一種程序模式,即使不知道一個以上智能指示器所參照的對象被破壞的時間,也能獲得明確破壞客體的效果。
如果要將Dispose Pattern運用到智能類客體上,作爲客體的成員變數,具有"自我狀態",這意味着客體是否已經被破壞,無法使用。 如果自己的狀態是"已經破壞的狀態",那麼在參考客體時就會發生錯誤,否則就要讓其正常執行。
下面是運用Dispose Pattern的例子。
Dispose Pattern 是 在Java或C#等智能指示器和Garbage Collector的程序設計語言中也有涉及。
線程實用程式
ProudNet提供了一些線程實用類。
類別 | 註釋 |
---|---|
Proud.Thread | 線程可以很容易地生成和破壞。 |
Proud.CriticalSection | 可以創建critical section。 |
Proud.CriticalSectionLock | 可以lock和unlock。 |
字符串類
ProudNet使字符串類Proud.String, Proud.StringA使字符串像ATL或STL的字符串類一樣可以簡便地處理。
使用 .Net Framework 的程序具有名爲 System.string 的符號。 因此.Net Framework混用時,可能需要註明System或Proud中的一個命名空間。
舉例如下。
- 創建字符串功能(format)
Proud.StringT 提供了創建字符串的功能, 如 sprintf() 。
- 字符串處理性能
Copy-on-write
字符串長度測量
Proud.StringT.GetLength在調用後立即返回預先測量的字符串長度。 即與strlen()不同。
Proud.StringT 和 int 和 float 一樣, 不使用 thread safe 。 因此,同時從多個執行緒存取同一個字串物件是不安全的(除非所有執行緒都只是讀取)。
這一點與ATL或STL的字符串類別相同。
Timer Queue
Timer Queue是在線程池中執行tick event的模塊,在Windows XP,2000年以後版本的操作系統上提供名爲Windows Timer Queue的API。
每隔一段時間運行用戶指定的函數, 該函數在線程池中的一個線程中運行。 如果所有線程正在運行(running state) 函數的執行將保留到線程中出現完成歷史任務線程爲止。
在Timer Queue中呼叫的用戶函數是從線程池中的線程中選擇一個,如果之前正在運行的用戶函數處於未運行狀態,也有無事可做的線程(idle state),則選擇該線程並執行用戶函數。
假設有以下工作清單。
黑箭頭爲0.1s,A、B、C、D、E是每0.1s應做的工作項目。 A、D在0.1秒內結束,B在0.1秒內結束,C、E在0.1秒內無法結束。
如果是服務器主環方法,則這些操作項目如下圖所示。 由於在一個線程中運行所有任務項目,D、E不能按時啓動。
然而,在Timer Queue方法中,動員了另一個線程來運行D,並且E及時運行在先前完成C的線程中。
及時啓動必要任務,必要時進一步調動線程。
Timer Queue主要在服務器程序中使用,因爲用戶函數可能同時在兩個或多個線程中運行。
實現並列性,但需承受並列性所具有的危險性,使用前請判斷該功能是否必要。
如果錯誤地使用 Timer Queue 服務器過程的線程會爆炸性地增加,對性能產生不利影響。 如果沒有必須使用 Timer Queue的原因, 請在 Proud.CTimerThread 或服務器上使用計時器環路, RMI, 事件處理 。
- 如何使用計時器隊列
您需要存取 Proud.CTimerQueue 類別。 這個類別是一個singleton。
如果將調用函數和調用週期設置爲 Proud::NewTimerParam 結構,並將其作爲參數添加到 Proud.CTimerQueue.NewTimer 中,則會獲得 Proud.CTimerQueueTimer 對象。 然後,在破壞 Proud.CTimerQueueTimer 對象之前,指定的用戶函數每隔一段時間運行一次。
留下日誌
在開發網絡遊戲的過程中,必然需要留下各種執行記錄(日誌)的功能。 ProudNet爲此提供日誌留存功能。
ProudNet的登錄功能以非同步方式運行,因此,在調用要留下登錄的方法後,方法立即返回。 此外,將單獨線程的實際日誌記錄在文件或數據庫中。
- 日誌記錄到文件
Proud::CLogWriter 類是允許將日誌寫入文件的類 。
- 日誌記錄到數據庫
Proud::CDbLogWriter 類是允許將日誌寫入DB 的類 。
爲此,您必須運行 Sample/DbmsSchema 文件夾中的 LogTable.sql,以預先生成 LogTable 。 DBMS的建立參考樣品數據庫建立的程序。
延遲測量功能
ProudNet以StopWatch的形式提供延遲測量功能。
如果是可用的版本,則必須使用比現有延遲測量函數更準確的該功能,而不是服務器的GetLastPing或GetRecentPing。
(1) 開始延遲測量
調用 StartRoundTripLatencyTest 將開始要測量延遲的目標和 relay 。
(2) 延遲測量結束
如果您想在先前指定的測試Duration之前停止測試, 請調用StopRoundTripLatencyTest函數 。 如果直到testDuration結束爲止不呼叫StopRoundTripLatencyTest,則將自動停止測量。
(3) 獲取延遲測量值
PIDL 編譯器插件
這是 Visual Studio 的附加元件,可協助您輕鬆設定 PIDL (ProudNet IDL) 檔案的自訂建置。
- 安裝
1. 運行 <安裝路徑>\ProudNet\util\PIDL-addon.vsix。
2. 選擇要安裝附加元件的 Visual Studio 並繼續安裝。
3. 安裝成功完成後,會顯示如下圖所示。
- 刪除
可以透過Tools → Extensions and Updates選單將其刪除。
對於 Visual Studio 2010, Tools → Extension Manager
- 新增PIDL檔案視窗
調用 PIDL 新增視窗。 選擇選擇項目 → 右鍵 → Add new PIDL file
輸入 PIDL 文件名 。
顯示添加 PIDL 文件的路徑 。
添加外部 PIDL 文件 。
創建新的 PIDL 文件 。
關閉 PIDL 附加窗口 。
- 添加 PIDL 文件
輸入要添加的 PIDL 文件名
點擊 New PIDL
如上圖所示,添加了PIDL文件,該文件默認設置Custom Build。 與默認設置不同時,可通過文件屬性更改功能進行更改。
- PIDL 文件屬性窗口
調用 PIDL 屬性窗口 。
選擇 PIDL 文件 → 右鍵點擊 → Properties 選擇
檢查/ 更改 PIDL 文件中的 Custom Build Tool 設置 。 PIDL Compiler Location: 設置 PIDL 編譯器位置 。 PIDL Compiler Location is Relative: 輸入路徑的絕對/相對與否值。 Output Directory (All Languages): 設置輸出路徑 。 Output Directory is Relative (All Languages): 輸入路徑的絕對/相對與否值。
各語言設置窗口:可按各C++、C#、Java、Unreal Script語言生成。
特定於語言的設定視窗: Generate Code: C++ 默認 Yes, 其餘語言是 False (可根據需要配置) C++ Implementation File Extension: 僅限C++。
Last updated