翻譯來自:c++11 multithreading – part 4: data sharing and race conditions
在多執行緒環境中,執行緒之間的資料共享非常容易。但是,這種易於共享的資料可能會導致應用程式出現問題。這樣的問題之一就是比賽條件。
什麼是比賽條件?
競爭條件是一種在多執行緒應用程式中發生的錯誤。
當兩個或多個執行緒並行執行一組操作時,它們將訪問同一記憶體位置。同樣,其中的乙個或多個執行緒會修改該記憶體位置中的資料,這有時會導致意外結果。
這稱為競爭條件。
競賽條件通常不會每次都發生,因此通常很難找到和複製。僅當兩個或多個執行緒的相對執行順序導致意外結果時,它們才會發生。讓我們通過乙個例子來理解,
競賽條件的實際示例:
讓我們建立乙個wallet類,該類在內部維護金錢並提供服務/功能,即addmoney()。該成員函式使錢包物件的內部貨幣增加指定的數量。
現在讓我們建立5個執行緒,所有這些執行緒將共享wallet類的同一物件,並使用其addmoney()成員函式並行向內部貨幣新增1000。class
wallet
intgetmoney()
void
addmoney
(int money)}}
;
因此,如果最初在錢包中的錢為0。那麼在完成所有執行緒的執行後,在wallet中的錢應該為5000。
但是,由於所有執行緒都在同時修改共享資料,因此在某些情況下,最終錢包中的錢可能少於5000。
讓我們測試一下
由於同一wallet類物件的addmoney()成員函式執行了5次,因此其內部貨幣預計為5000。但是由於addmoney()成員函式並行執行,因此在某些情況下mmoney會比5000小得多,即int
testmultithreadedwallet()
for(
int i =
0; i < threads.
size()
; i++
)return walletobject.
getmoney()
;}intmain()
}return0;
}
output is,
error at count = 971 money in wallet = 4568 error at count = 971 money in wallet = 4568 error at count = 972 money in wallet = 4260 error at count = 972 money in wallet = 4260 error at count = 973 money in wallet = 4976 error at count = 973 money in wallet = 4976
這是一種競爭條件,因為這裡有兩個或更多執行緒試圖同時修改同一記憶體位置並導致意外結果。
為什麼會這樣?
每個執行緒並行增加相同的「 mmoney」成員變數。儘管似乎只有一行,但實際上此「 mmoney ++」已轉換為三個機器命令,
現在假設在特殊情況下,上述命令的執行順序如下:
在這種情況下,乙個增量將被忽略,因為不是將兩次「 mmoney」變數遞增一次,而是將不同的暫存器遞增,並且「 mmoney」變數的值被覆蓋。
假定在此方案之前,mmoney為46,如上圖所示,它增加了2倍,因此預期結果為48。但是由於在上述方案中的競爭條件,mmoney的最終值將僅為47。
這稱為競爭條件。
如何解決比賽條件?
為了解決這個問題,我們需要使用lock機制,即每個執行緒需要在修改或讀取共享資料之前獲得乙個鎖,並且在修改資料之後,每個執行緒都應該解鎖該鎖。
C 11多執行緒(4)
死鎖 1 死鎖定義 如果一組程序中的每乙個程序都在等待僅由該組程序中的其他程序才能引發的事件,那麼該組程序是死鎖的 deadlock 2 死鎖產生的四個必要條件 1 互斥 2 不可剝奪 3 保持且請求 4 迴圈等待 3 解決死鎖的方法 1 預防死鎖,破壞死鎖產生的四個必要條件之一 2 避免死鎖,銀行...
c 11 多執行緒 4 condition
note1 條件變數的等待函式wait lck 需要與乙個互斥鎖搭配使用 要明白搭配使用的機理,否則理解上會造成混亂 在呼叫wait時 note2 condition variable類更多成員函式含義和用法可見.例項 include include include include includes...
C 11多執行緒學習 共享資源鎖
include thread include list include mutex include find include printf using namespace std listsome list mutex some mutex void add to list int new valu...