聯(lián)系我們 - 廣告服務(wù) - 聯(lián)系電話:
您的當(dāng)前位置: > 關(guān)注 > > 正文

關(guān)注:如何使用lock_guard鎖定mutex?java中mutex的使用方法

來(lái)源:CSDN 時(shí)間:2023-01-16 07:55:05

mutex用來(lái)協(xié)助采取獨(dú)占方式控制對(duì)資源的并發(fā)訪問(wèn),這里的資源可能是一個(gè)對(duì)象,或多個(gè)對(duì)象的組合,為了獲得獨(dú)占式的資源訪問(wèn)能力,相應(yīng)的線程必須鎖定mutex,這樣可以防止其它線程也鎖定該mutex。

下面兩條線程如果沒(méi)有使用mutex來(lái)同步,則輸出結(jié)果會(huì)是112233。

mutex g_mutex;void print123() {g_mutex.lock();for (int i = 0; i < 3; i++) {this_thread::sleep_for(chrono::milliseconds(100));cout << i + 1;}g_mutex.unlock();} int main(){thread(print123).detach();thread(print123).detach();//123123system("pause");}

你應(yīng)該確保mutex對(duì)象調(diào)用lock后,即使發(fā)生異常也會(huì)調(diào)用unlock,否則有可能造成資源被永遠(yuǎn)鎖住或者死鎖。


(資料圖片)

為此我們可以使用lock_guard來(lái)進(jìn)行l(wèi)ock和unlock,lock_guard在構(gòu)造時(shí)會(huì)lock,析構(gòu)時(shí)會(huì)unlock,使用大括號(hào)對(duì)可以加快lock_guard的析構(gòu),需要注意的是lock_guard一定要分配變量名,否則不會(huì)有效果。

void print123(){lock_guard lockGuard(g_mutex);for (int i = 0; i < 3; i++) {this_thread::sleep_for(chrono::milliseconds(100));cout << i + 1;}}

同一線程多次鎖定mutex會(huì)導(dǎo)致程序終止,而recursive_mutex則不會(huì),這個(gè)mutex允許同一線程多次鎖定。

recursive_mutex g_mutex;void print123(){g_mutex.lock();g_mutex.lock();for (int i = 0; i < 3; i++) {this_thread::sleep_for(chrono::milliseconds(100));cout << i + 1;}g_mutex.unlock();g_mutex.unlock();}

有時(shí)候線程想要鎖定mutex,但又不想其它線程已鎖定mutex時(shí)阻塞,這種情況下可以使用try_lock,它試圖鎖定mutex,成功就返回true,失敗返回false。

為了等待特定長(zhǎng)度的時(shí)間,你可以使用timed_mutex或recursive_timed_mutex的try_lock_for或try_lock_until方法。

由于try_lock在返回true時(shí)會(huì)鎖定mutex,為了防止lock_guard重復(fù)鎖定,需要傳遞參數(shù)adopt_lock。

void print123() {if (g_mutex.try_lock()) {lock_guard  lockGuard(g_mutex,adopt_lock);for (int i = 0; i < 3; i++) {this_thread::sleep_for(chrono::milliseconds(100));cout << i + 1;}} else {cout << "mutex locked" <thread(print123).detach();thread(print123).detach();system("pause");}

通常一個(gè)線程一次只鎖定一個(gè)mutex,然而有時(shí)候必須鎖定多個(gè)mutex,如果一個(gè)個(gè)鎖定,有可能出現(xiàn)鎖定了第一個(gè)mutex,而無(wú)法鎖定第二個(gè)mutex的情況。這種情況下可以使用全局函數(shù)lock鎖定多個(gè)mutex。

mutex g_mutex1;mutex g_mutex2;void print123() {lock(g_mutex1, g_mutex2);lock_guard lockGuard1(g_mutex1, adopt_lock);lock_guard lockGuard2(g_mutex2, adopt_lock);for (int i = 0; i < 3; i++) {this_thread::sleep_for(chrono::milliseconds(100));cout << i + 1;}} int main(){thread(print123).detach();thread(print123).detach();system("pause");}

使用全局函數(shù)try_lock嘗試鎖定多個(gè)mutex,如果鎖定所有mutex則返回-1,否則返回第一個(gè)失敗的mutex的索引(從0開(kāi)始),并且所有被成功lock的mutex會(huì)又被unlock。

mutex g_mutex1;mutex g_mutex2;void print123() {lock(g_mutex1, g_mutex2);lock_guard lockGuard1(g_mutex1, adopt_lock);lock_guard lockGuard2(g_mutex2, adopt_lock);for (int i = 0; i < 3; i++) {this_thread::sleep_for(chrono::milliseconds(100));cout << i + 1;}}void printLockState(){auto result = try_lock(g_mutex1, g_mutex2);cout << result << endl;if (result == -1) {lock_guard lockGuard1(g_mutex1, adopt_lock);lock_guard lockGuard2(g_mutex2, adopt_lock);}} int main(){thread(print123).detach();thread(printLockState).detach();system("pause");}

除了lock_guard,C++還提供一個(gè)類似的類unique_lock,它比lock_guard更靈活,unique_lock允許你明確指定何時(shí)鎖定或解鎖mutex,而lock_guard總是鎖定mutex,如果unique_lock析構(gòu)時(shí)mutex仍被鎖住,析構(gòu)函數(shù)會(huì)自動(dòng)調(diào)用unlock,如果沒(méi)有則不做任何事。

mutex g_mutex1;timed_mutex g_mutex2; int main(){//嘗試鎖定mutex,但不會(huì)阻塞unique_lock uniqueLock1(g_mutex1, try_to_lock);//嘗試鎖定mutex,不超過(guò)10秒unique_lock uniqueLock2(g_mutex2, chrono::seconds(10));//主動(dòng)調(diào)用lock,try_lock,try_lock_for等才會(huì)鎖定unique_lock uniqueLock3(g_mutex1, defer_lock);//通過(guò)已鎖定的mutex初始化unique_lock uniqueLock4(g_mutex1, adopt_lock);//判斷有沒(méi)有鎖定mutexcout << (uniqueLock1 ? "locked" : "unlocked")<< endl;cout << uniqueLock1.owns_lock() << endl;//解鎖mutexuniqueLock1.unlock();//鎖定mutexuniqueLock3.lock();system("pause");}
責(zé)任編輯:

標(biāo)簽:

相關(guān)推薦:

精彩放送:

新聞聚焦
Top