2012-12-20 216 views
3

我目前正在開始使用Allegro跨平臺庫在C上進行獨立遊戲開發。我想我會將諸如輸入,聲音,遊戲引擎和圖形之類的東西分離到各自的線程中,以提高程序的穩健性。沒有多線程的經驗,我的問題是:多線程和互斥鎖

如果我在內存中有一段數據(比如指向數據結構的指針),一個線程可以隨意寫入,從中隨意讀取,還是每個線程都必須使用互斥鎖來鎖定內存,然後讀取或寫入,然後解鎖?

特別是,我在考慮遊戲引擎和視頻渲染器之間的交互。 (這是2D格式。)我的計劃是讓引擎處理用戶輸入,然後吐出合適的音頻和視頻,送到揚聲器和監視器。我在想,我有一個全球性的指針到下一個位圖在屏幕上繪製,併爲遊戲引擎和渲染器的代碼將是這樣的:

ALLEGRO_BITMAP *nextBitmap; 
boolean using; 

void GameEngine() 
    { 

    ALLEGRO_BITMAP *oldBitmap; 

    while (ContinueGameEngine()) 
    { 
    ALLEGRO_BITMAP *bitmap = al_create_bitmap (width, height); 
    MakeTheBitmap (bitmap); 
    while (using) ; //The other thread is using the bitmap. Don't mess with it! 
    al_destroy_bitmap (nextBitmap); 
    nextBitmap = bitmap; 
    } 

    } 

void Renderer() 
    { 

    while (ContinueRenderer()) 
    { 
    ALLEGRO_BITMAP *bitmap = al_clone_bitmap (nextBitmap); 
    DrawBitmapOnScreen (bitmap); 
    } 

    } 

這似乎不穩定.. 。可能會在al_clone_bitmap的電話中發生,但我不太確定如何處理這樣的事情。我會在位圖上使用互斥鎖,但互斥鎖似乎需要時間鎖定和解鎖,我希望這兩個線程(特別是遊戲引擎線程)儘可能快地運行。我也讀了一些叫做條件的東西,但我完全不知道一個條件如何適用或有用,儘管我確定它們是。有人能指點我一個關於互斥體和條件的教程(最好是POSIX,而不是Windows),所以我可以試着弄明白這一切嗎?

+0

一些Allegro說明:Allegro已經在特定平臺所需的不同線程上運行各種組件。還要注意,給定顯示的所有繪圖操作都需要從創建顯示的同一個線程發生。如果從輔助線程加載位圖,則可以在顯示線程上調用'al_clone_bitmap()',但不應該在每個幀上都這樣做。國際海事組織,你不應該因爲使用更多線程的理由而釣魚。 – Matthew

回答

1

如果我在存儲器中的數據的部分(比如,一個指向數據 結構),是它好一個線程寫入它的意志和 另一個閱讀從它隨意

答案是「它取決於」,通常意味着「不」。

根據你寫什麼/讀取,並且根據你的程序的邏輯,你可以與野生結果或腐敗風,如果你嘗試寫,沒有同步閱讀,你不能絕對確保寫入並且讀取是原子的。

所以,你應該只使用一個互斥體,除非:

  1. 你絕對相信,寫入和讀取是原子,而你絕對相信,一個線程只能讀取(理想情況下,你會使用一些對原子操作(如WinAPI中的Interlocked函數家族)的特定支持)。
  2. 你絕對需要從未鎖定的微小性能增益。

另外值得一提的是您的while (using);結構將是一個很多更可靠,正確的,並且如果使用可能會甚至獲得更好的效果spin lock(如果你又絕對相信你需要一個自旋鎖,而不是互斥)。

0

'google'中有很多手冊頁。搜索他們。我在幾個搜索分鐘內找到了http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html

此外,從一個這麼小的例子開始,增加難度。具有線程創建和終止,線程返回,線程sincronization的Firstable。繼續posix互斥和條件並理解所有這些條款。

一個重要的文檔飼料是Linux手冊和信息頁。

好運

1

您需要的工具被稱爲原子操作這將確保讀者線程只讀取其他線程寫入的整個數據。如果您不使用這些操作,則數據只能被部分讀取,因此讀取的內容可能對您的應用程序而言可能毫無意義。

新標準C11具有這些操作,但尚未廣泛實施。但是許多編譯器應該有擴展來實現這些。例如,gcc具有一系列內置函數,以__sync前綴開頭。

0

如果非要在存儲器中的數據的部分(比如說,一個指針指向一個數據結構),是它好用於一個線程寫入它隨意,另一個隨意從中讀取,或者將各線程必須使用互斥鎖來鎖定內存,然後讀取或寫入,然後解鎖?

如果您在內存中有兩個不同線程正在讀取和寫入的數據部分,這稱爲關鍵部分,並且是消費者和生產者的常見問題。

有跡象表明,這個問題講了許多資源:

但是,是的,如果你要使用兩個不同的線程讀取和寫你必須實現互斥或其他形式的鎖定和解鎖。