對主循環的理解

客戶端主環

ProudNet的客戶端以polling方式接收信息或發生事件時,RMI呼叫回饋或事件處理器回饋僅在遊戲客戶端主循環中呼叫特定函數時的線程中回饋。

主要是因爲遊戲客戶端具有快速轉動的環路,導致意外線程活動, 通過上述方法設計,客戶端開發者減輕了複雜線程編程的負擔。

服務器主環

- 接收和事件回呼

遊戲服務器利用所有CPU,在接近DB期間,爲了對其他客戶端進行接收處理,利用Thread pooling,ProudNet也以這種方式啓動,因此具有以下特點。

  • 服務器啓動時,會生成一個單獨的Thread pool

  • 遊戲客戶端需要每隔一段時間調用函數進行接收處理,才能處理堆積的接收信息,但服務器不需要調用這種函數。

  • 服務器發生事件或RMI接收時,會在Server擁有的Thread pooling中回撥。

  • 對於同一客戶端的活動或RMI接收,2個以上線程中RMI接收不能同時回饋,但ProudNet必須按到達順序回饋RMI接收。 當然,針對不同客戶的事件,RMI會同時發生回撥。

  • 所有線程在回饋線程運行期間發生RMI或事件時不會立即發生回饋,但在回饋線程完成時,該回饋處於待機狀態。

  • 即使用戶實施的回撥例程運行時間較長,網絡通信也不會發生故障,因此無需自行實現單獨的線程池。

以下是在客戶端A、B、C被服務器容納的狀態下,分別表示因RMI或事件而在Server內的queue等待的狀態的圖片。

A1,A2,A3 -> 客戶端 A 的事件或 RMI B1,B2,B3 -> 客戶端 B 的事件或 RMI 線程池共有2個線程。

這時根據規則執行如下。

  • A1、A2、A3不能同時運行。

  • B1、B2、B3和C1、C2、C3同樣不是同時運行的。

  • A1、A2、A3之一和B1、B2、B3之一、C1、C2、C3之一可以同時運行。

  • 由於線程池中只有2個線程,A、B、C中的2個線程被篩選並回饋,但回饋程序首先完成線程的線程對未篩選的客戶端進行RMI或事件回饋。

- 定時回撥

就像遊戲客戶端一樣,遊戲服務器也可以每隔一段時間處理一些事情。 在這些情況下,有一種方法具有以下簡單的環。

while(1)
{
    do_something(); // 執行世界轉換操作
    Sleep(1); // 等待一段時間
}

還有一種方法是使用 Proud.CTimerThreadProud.CTimerQueue 在單獨線程中運行上述循環。 但是,我建議您如何直接從服務器線程池調用自定義計時器函數。

例如,當服務器只有一個線程時,如果定時器函數和活動回撥是同一線程,則可以節省critical section訪問次數。 ProudNet還內置這些功能,敬請參考。

Last updated