2017-09-26 32 views
0

我有一個應用程序呈現到一個線程中的紋理,另一個線程從這個紋理讀取數據。兩個線程之間的上下文是共享的。在閱讀線程將讀取部分數據的情況下,是否有可能出現競爭條件?是否可以在寫入時渲染紋理?

+3

是的,這基本上是數據競賽的完美設置。 –

+0

@DietrichEpp我在網上讀到,當有東西從兩個不同的線程寫入上下文時,可能會發生問題,但是我找不到任何說明寫入的影響,只能從另一個讀取。 – Kyle

回答

1

the OpenGL 4.6 core spec從,第5.3.1節:

對象T的內容被認爲已經改變一次這樣的命令,如第5.3節描述的已完成。可以通過調用Finish或調用FenceSync並在關聯的同步對象上執行WaitSync命令來確定完成命令1。

  1. 兩個或多個線程被寫入到存儲器中的相同位置,和

  2. 至少線程之一是:

通常,數據競爭時發生書寫和

  • 線程之間沒有同步。

  • 你可以看到,在OpenGL中,你需要或者等待Finish()WaitSync()返回知道你的操作是同步的。有額外的規則,註釋部分5.3.3:

    規則4如果對象T的內容在比當前上下文之外的上下文被改變時,T必須被附接或重新連接到至少當前上下文中的一個綁定點或當前綁定的容器對象C的至少一個連接點,以保證T的新內容在當前上下文中可見。

    所以,如果你寫在線程A引起的紋理,在線程B讀取它,你必須做到以下幾點:

    1. 創建一個同步對象。

    2. 一旦寫入完成,就從線程A發出同步對象的信號。

    3. 等待在線程B的同步對象

    4. 重新綁定在線程B.紋理

    這些步驟都完成之後,你可以從線程B.紋理讀取

    注:您可能會發現與數據種族代碼,如果你對測試它將會「正常工作」你自己的電腦。這並不奇怪......有時候它會起作用,有時候它不會。也許它會一直在你的電腦上工作,並炸燬別人的電腦。更好的做法是通過線程同步來實現,只是測試不夠好。

    1

    可能,絕對是。

    雖然沒有必要。在GLsync和glFinish中有很好的同步原始碼,你沒有理由不使用它們。

    究竟是什麼影響來自數據競賽是未指定的。您最終可能會讀取一半紋理,您可能會在驅動程序中調用致命錯誤,或者它可能會停止。