1. 程式人生 > >條件競爭和惡性條件競爭

條件競爭和惡性條件競爭

mutex banner 對數 tar 正在 例子 AMM aik 如同

競爭條件指多個線程或者進程在讀寫一個共享數據時結果依賴於它們執行的相對時間的情形。 競爭條件發生在當多個進程或者線程在讀寫數據時,其最終的的結果依賴於多個進程的指令執行順序。 例如:考慮下面的例子 假設兩個進程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)。

條件競爭和惡性條件競爭