每日快看:初識互斥量

來源: 嗶哩嗶哩 2023-07-01 22:56:00


(資料圖)

Case 0 :

運行的結(jié)果大概率是字母和數(shù)字混合在一起被打印出來,并不會先打印完全部數(shù)字再打印字母。這是因為線程的執(zhí)行并沒有確定的先后順序。

Case 1 :

當(dāng)多個線程涉及到共享數(shù)據(jù)時,為了防止條件競爭和數(shù)據(jù)訪問沖突,需要用到互斥量(Mutex)。

訪問共享數(shù)據(jù)前,將數(shù)據(jù)鎖住,在訪問結(jié)束后,再將數(shù)據(jù)解鎖。當(dāng)一個線程使用特定互斥量鎖住共享數(shù)據(jù)時,其他的線程想要訪問鎖住的數(shù)據(jù),都必須等到之前那個線程對數(shù)據(jù)進(jìn)行解鎖后,才能進(jìn)行訪問——這就是互斥量的作用。

Case 0的優(yōu)化:

Case 1的優(yōu)化:

使用互斥量來保護(hù)數(shù)據(jù),并不是僅僅在每一個成員函數(shù)中都加入一個std::lock_guard對象那么簡單,一個指針或引用,也會讓這種保護(hù)形同虛設(shè)。

在上述代碼中,函數(shù)process_data使用std::lock_guard來創(chuàng)建一個互斥量的鎖保護(hù)區(qū)域,確保在同一時間只有一個線程可以訪問Data對象的內(nèi)容。但是在boom函數(shù)中調(diào)用process_data函數(shù)時,content的引用被傳遞給了malicious_func函數(shù),從而使得通過unprotected_content指針可以繞過互斥量的保護(hù),直接修改Data對象的內(nèi)容,如果此時有其他線程在訪問和修改Data對象,又將引發(fā)數(shù)據(jù)競爭和未定義的行為。

Warning:切勿將受保護(hù)數(shù)據(jù)的指針或引用傳遞到互斥鎖作用域之外,無論是函數(shù)返回值,還是存儲在外部可見內(nèi)存,亦或是以參數(shù)的形式傳遞到其他函數(shù)中去。

關(guān)鍵詞:

你可能會喜歡: