Unigine中綫程操作和鎖的情況

一般的,我們在C++中有互斥鎖mutex , 條件鎖,自旋鎖SpinLock , 讀寫鎖RWLock .當然還有一些基於mutex的鎖,

C++11中提供的有:

  • std::mutex,最基本的 Mutex 類。
  • std::recursive_mutex,遞歸 Mutex 類。
  • std::time_mutex,定時 Mutex 類。
  • std::recursive_timed_mutex,定時遞歸 Mutex 類。

Lock有2類

  • std::lock_guard,與 Mutex RAII 相關,方便線程對互斥量上鎖。
  • std::unique_lock,與 Mutex RAII 相關,方便線程對互斥量上鎖,但提供了更好的上鎖和解鎖控制。

 

在Unigine中,其內部提供的Thread類相關方法,也大同小異。

  1. 原子操作AtomicAdd,實際上調用了window平臺的_InterlockedExchangeAdd, linux上的__sync_fetch_and_add 而已。

Unigine提供的方法有AtomicAdd,AtomicGet等。除了Thread類本身用外,只有內置Memory對象用到了

  1. 原子級別操作的AtomicCAS(標準CAS比較/交換算法)使用了windows的_InterlockedCompareExchange64,linux上的__sync_val_compare_and_swap
  2. 支持SpinLock ,基於上述AtomicAdd等原子操作,這在Unigine用的類對象比較廣泛,tileset, material , render,property等。
  3. 支持RWLock,基於上述AtomicAdd等原子操作,

這方面,Unigine的TerrainGlobal和FileSystem,用的比較多。

 

總體個人感覺,關於多線程或者線程鎖相關的內容,與其用Unigine內置的,還不如自己寫,畢竟它是個引擎,不是個大雜燴。

 

以下借用刷草的列子,介紹下如何使用Unigine中的Thread對象WorldSpawnGrassThread,

classWorldSpawnGrassThread : publicThread

{

public:

       WorldSpawnGrassThread() {}

       virtual ~WorldSpawnGrassThread() {}

 

protected:

       virtualvoid process();

};

 

voidWorldSpawnGrassThread::process()

{

       while (isRunning())

              engine.world->processSpawnGrass();

}

重要方法就是void process(), 父線程中的virtual函數實現即可。

早期Uniginev2.5的時候刷草代碼沒有做線程的lock,在Update時刪除草對象等行爲時會奔潰。較新的代碼中每個線程對象分配了一個類似下面的lock對象。

       volatileintworld_spawn_mesh_clutter_lock;

在進行多線程操作的時候用

       SpinLock(lock, 0, 1); //開啓開啓自旋鎖

XXX-》執行很多內容

       SpinLock(lock, 1, 0); //關閉自旋鎖

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章