少高潮爽了在观看奂费_奶水无码专区_欧美亚洲三级日韩_91精品国产综合香蕉_秋霞伦理电影在线_GOGO亚洲肉体艺术欣赏图片_一本一道a√无码中文字幕_免费看一级毛片无码区_内射视频网站在线观看_国产激情视频精品中文

編程代碼
新聞詳情

C++11多線程編程(八)——死鎖問(wèn)題

發(fā)布時(shí)間:2021-01-07 14:00:41 瀏覽次數(shù):2223

一、死鎖現(xiàn)象

看到“死鎖”二字,你是不是慌得不知所措。死鎖,顧名思義就是這個(gè)鎖死掉了,再也動(dòng)不了了。那死鎖是怎么產(chǎn)生的呢?當(dāng)你對(duì)某個(gè)資源上鎖后,卻遲遲沒(méi)有釋放或者根本就無(wú)法釋放,導(dǎo)致別的線程無(wú)法獲得該資源的訪問(wèn)權(quán)限,進(jìn)而程序無(wú)法運(yùn)行下去,有點(diǎn)像是阻塞的現(xiàn)象。但是阻塞是一種正?,F(xiàn)象,而死鎖可以說(shuō)是一種bug,必須要處理。

C++11多線程編程(八)——死鎖問(wèn)題

那么我現(xiàn)在就舉個(gè)死鎖的例子,來(lái)分析分析。

#include <iostream>
#include <thread>
#include <mutex>
using namespace std;
 
mutex mt1;
mutex mt2;
void thread1()
{
    cout << "thread1 begin" << endl;
    lock_guard<mutex> guard1(mt1);
    this_thread::sleep_for(chrono::seconds(1));
    lock_guard<mutex> guard2(mt2);
    cout << "hello thread1" << endl;
}
void thread2()
{
    cout << "thread2 begin" << endl;
    lock_guard<mutex> guard1(mt2);
    this_thread::sleep_for(chrono::seconds(1));
    lock_guard<mutex> guard2(mt1);
    cout << "hello thread2" << endl;
}
 
int main()
{
    thread t1(thread1);
    thread t2(thread2);
    t1.join();
    t2.join();
    cout << "thread end" << endl;
    return 0;
}

二、死鎖分析

因?yàn)槌绦蜻\(yùn)行的是非??斓模詾榱水a(chǎn)生死鎖現(xiàn)象,我們各自休眠了1秒。

運(yùn)行以上程序可以發(fā)現(xiàn),程序在輸出完“thread1 beginthread2 begin”后,就卡在那里,程序運(yùn)行可能發(fā)生了以下這種情況:

thread1              thread2
mt1.lock()           mt2.lock()
//死鎖               //死鎖
mt2.lock()           mt1.lock()

thread1中的mt2在等待著thread2的mt2釋放鎖,而thead2中mt1卻也在等待著thread1的mt1釋放鎖,互相都在等待著對(duì)方釋放鎖,進(jìn)而產(chǎn)生了死鎖。必須強(qiáng)調(diào)的是,這是一種bug,必須避免。那么如何避免這種情況呢?

三、死鎖解決

1、每次都先鎖同一個(gè)鎖

比如像上面thread1和thread2線程,我們每次都先鎖mt1,再鎖mt2,就不會(huì)發(fā)生死鎖現(xiàn)象。

2、給鎖定義一個(gè)層次的屬性,每次按層次由高到低的順序上鎖,這個(gè)原理也是每次都先鎖同一個(gè)鎖。

C++標(biāo)準(zhǔn)庫(kù)中提供了std::lock()函數(shù),能夠保證將多個(gè)互斥鎖同時(shí)上鎖。

std::lock(mt1, mt2);

那么既然在最前面就已經(jīng)上鎖了,后面就不需要上鎖了,而C++標(biāo)準(zhǔn)庫(kù)并沒(méi)有提供std::unlock()的用法,所以還是需要用到lock_guard,但是需要修改一點(diǎn)。加個(gè)std::adopt_lock就可以了。

lock_guard<mutex> guard1(mt1, adopt_lock);
lock_guard<mutex> guard2(mt2, adopt_lock);

這個(gè)表示構(gòu)造函數(shù)的時(shí)候不要給我上鎖,到析構(gòu)的時(shí)候你要記得給我解鎖。

這個(gè)就是死鎖的一些解決方法,同時(shí)大家一定要記得盡量不要一段定義域內(nèi)多次使用互斥鎖,如果不可避免的要使用,一定要記得給鎖定義順序,或者使用要使用std::lock()上鎖。

相關(guān)閱讀:

在線客服 雙翌客服
客服電話
  • 0755-23712116
  • 13822267203