2008年8月29日 星期五

Objects Streaming in Multi-Thread

這一篇,算是整理我自己的設計思路。

簡單來說,這功能是讀取資料流裡面的資料,然後產生相關的物件,包括遊戲中的物件,以及引擎核心的物件。當然免不了的,是必須放在多執行緒的環境中來進行,我們不能讓遊戲在進行中的時候,還要停下來等待讀取。

我做了個「不正式的」UML順序圖。

Object Streaming

幾個主要的步驟是這樣:在讀取之前,先做一些清除物件列表的事情,然後一個一個物件讀取,讀取完了,再對於這些讀取到的物件,連結它們的從屬關係。物件的產生是由物件的Factory函式來負責,Stream讀取了物件的Type Info之後,根據物件的類別呼叫對應的Factory函式。

物件的Factory函式要做幾個工作:產生新物件、將物件加入到Stream的物件列表中、讀取物件的內容資料。

在多執行緒的環境下,這樣的流程是沒有太大問題的,只要負責讀取的Stream不是各個執行緒共用的就好,而實際上也沒有必要這麼做。

但是遊戲中有幾種物件,資料量很大,很佔用記憶體空間,在設計上,我們必須讓這些資料變成共享的資料以節省不必要的記憶體浪費。而這些物件,在上面的流程裡,就會出問題了。

我用兩個不同的Stream,放在不同的執行緒裡,同時讀取一個共享的Object。由於物件的Factory函式中,並不會產生兩個獨立的Object,而是分享同一個Object,所以在讀取物件的內容資料時,就很容易發生資料打架的Race Condition。

為了解決這個問題,我又多開了一個執行緒。姑且叫做「共享資料專用執行緒」。這個執行緒的唯一工作,就是負責讀取這些共享物件的資料內容。執行緒會把工作存放在佇列中,一項一項的依序處理,這樣一來,資料打架的問題就不會再發生了。

當然,除了共享資料的物件之外,其他的物件也可以把讀取工作交辦給這個執行緒來做,不過我並不打算這麼做,因為這些物件並沒有資料打架的問題,沒有必要多花費一道手續跟時間,而且對這個專用執行緒來說,這麼多物件都交給它讀取,太操了...

沒有留言: