標籤:互斥 tin 指令 ram 記憶體 href get 進程 mod
競爭條件指多個線程或者進程在讀寫一個共用資料時結果依賴於它們執行的相對時間的情形。 競爭條件發生在當多個進程或者線程在讀寫資料時,其最終的的結果依賴於多個進程的指令執行順序。例如:考慮下面的例子假設兩個進程P1和P2共用了變數a。在某一執行時刻,P1更新a為1,在另一時刻,P2更新a為2。因此兩個任務競爭地寫變數a。在這個例子中,競爭的“失敗者”(最後更新的進程)決定了變數a的最終值。多個進程並發訪問和操作同一資料且執行結果與訪問的特定順序有關,稱為競爭條件。 惡性條件競爭通常發生於完成對多於一個的資料區塊的修改時,例如,對兩個串連指標的修改因為操作要訪問兩個獨立的資料區塊,獨立的指令將會對資料區塊將進行修改,並且其中一個線程可能進行中時,另一個線程就對資料區塊進行了訪問。因為出現的機率太低,條件競爭很難尋找,也很難複現。如CPU指令連續修改完成後,即使資料結構可以讓其他並發線程訪問,問題再次複現的幾率也相當低。當系統負載增加時,隨著執行數量的增加,執行序列的問題複現的機率也在增加,這樣的問題只可能會出現在負載比較大的情況下。條件競爭通常是時間敏感的,所以程式以偵錯模式運行時,它們常會完全消失,因為偵錯模式會影響程式的執行時間(即使影響不多)。 如何避免惡性條件競爭? 1.這裡提供一些方法來解決惡性條件競爭,最簡單的辦法就是對資料結構採用某種保護機制,確保只有進行修改的線程才能看到不變數被破壞時的中間狀態。 2另一個選擇是對資料結構和不變數的設計進行修改,修改完的結構必須能完成一系列不可分割的變化,也就是保證每個不變數保持穩定的狀態,這就是所謂的無鎖編程(lock-freeprogramming)。不過,這種方式很難得到正確的結果。 3.另一種處理條件競爭的方式是,使用事務(transacting)的方式去處理資料結構的更新(這裡的"處理"就如同對資料庫進行更新一樣)。所需的一些資料和讀取都儲存在交易記錄中,然後將之前的操作合為一步,再進行提交。當資料結構被另一個線程修改後,或處理已經重啟的情況下,提交就會無法進行,這稱作為“軟體事務記憶體”(software transactional memory(STM))。
4.保護共用資料結構的最基本的方式,是使用C++標準庫提供的互斥量(mutex)。
條件競爭和惡性條件競爭