2011-06-21 83 views
3

這將在沒有互斥體的情況下完成。我只想知道它是否是線程安全的,即程序不會崩潰或類似。我並不在乎變量在讀取時可能處於錯誤狀態,因爲結果不是致命的(只有在不需要時纔會影響小數據結構的副本) 我正在使用Qt。我可以從線程A寫入一個變量,同時從線程B讀取相同的變量

以下是可能發生的情況:從主線程中,我將設置一個bool,它是qthread的成員。當我將bool設置爲true時或之後,qthread可能位於使用此bool的函數中(這是由主線程和qthread使用的函數,所有內容都已被保護並同步,因此沒有函數由兩個線程同時運行)

有點想起它,因爲這個布爾只被主線程使用反正我會檢查哪個線程在函數中,應該解決,但我仍然好奇。

+0

如果你想基於你的布爾同步線程,你應該使用某種等待事件。 –

+0

@Tony,不,不,不用於同步線程。 –

回答

10

你似乎在問什麼是良性種族。

例如,考慮一個整數變量,表示在0到100範圍內的進度值。當您從另一個線程遞增時,您可以從一個線程讀取它。您不介意在寫入之前讀取值,還是在寫入之後讀取值。你會很快再讀一遍,然後在寫完之後你會得到價值。 在這種情況下,比賽是良性的。然而,什麼可能不是良性的東西叫撕裂。硬件可能允許您讀取值,而只有部分內存已被其他線程寫入。

例如,寫入線程可能寫入低位字,然後讀取兩個字,然後寫入高位字。撕裂會導致不正確。

硬件確實提供關於撕裂的保證,但是它們在不同的架構之間有所不同。例如,對於4字節對齊的4字節寬的數據,x86具有原子訪問,即不撕裂。

如果您正在編寫可移植代碼,那麼您處於相當棘手的水域,因爲當前的標準不能保證原子性。如果你可以在你的硬件平臺上做出假設,那麼你可能會利用良性的比賽。

+0

好的謝謝,答案很多。我現在明白如果所討論的變量是一個指針,撕裂對程序來說可能是致命的。在我的情況下,它是一個不應該導致致命墮胎的布爾。無論如何,我仍然會避免這樣做。 –

+1

這裏有一篇關於良性種族潛在問題的有趣文章:[http://blog.corensic.com/2011/06/07/benign-data-races-considered-harmful/](http://blog。 corensic.com/2011/06/07/benign-data-races-considered-harmful/)。 –

2

你可以在沒有互斥但不寫的情況下閱讀。如果多個線程將寫入您的變量,您需要有某種同步機制來保護它。

如果線程B在線程A完成寫入之前讀取,如果這不是簡單類型,而是一些複雜類型,則可能會出現不一致狀態。

+5

即使對於簡單類型,也可能會出現不一致。 –

+0

@Oli,我想這是因爲沒有寫保證是原子的? –

+0

我不關心如果我得到一個錯誤,而是我不想訪問違規或分段錯誤或崩潰 –

1

你沒有提到一個平臺,但是如果你是一個Windows系統,在處理更簡單的類型時,你一定要看看::Interlocked...家族的SDK函數。

+0

我通常在Linux發行版上,但感謝提示。 –

相關問題