【多线程】多线程锁住的是什么、std::lock_guard<std::mutex> locker(mutex_)
通常不直接使用 mutex,lock_guard更加安全, 更加方便。
lock_guard簡(jiǎn)化了 lock/unlock 的寫(xiě)法, lock_guard在構(gòu)造時(shí)自動(dòng)鎖定互斥量, 而在退出作用域時(shí)會(huì)析構(gòu)自動(dòng)解鎖, 保證了上鎖解鎖的正確操作, 正是典型的 RAII 機(jī)制。
問(wèn)題1:
像std::lock_guard<std::mutex> locker(mutex_);這樣同一句代碼在多個(gè)位置出現(xiàn),我以前不太了解的時(shí)候,不知道他們是不是管理的是同一個(gè)互斥鎖mutex_?
-
std::lock_guard<std::mutex> locker(mutex_);這句話很具有誤導(dǎo)性,看著像是一個(gè)拷貝構(gòu)造函數(shù)的使用,像是新創(chuàng)建了一個(gè)鎖locker,并把一個(gè)互斥量mutex_拷貝給他。實(shí)則并非如此,而是一個(gè)std::lock_guard構(gòu)造函數(shù)傳入一個(gè)std::mutex類的參數(shù)。
-
這句話傳入的參數(shù)是一個(gè)互斥量mutex_,并不是一個(gè)lock_guard對(duì)象,所以不是拷貝構(gòu)造。 std::lock_guard類的構(gòu)造函數(shù)禁用拷貝構(gòu)造,且禁用移動(dòng)構(gòu)造。std::lock_guard類除了構(gòu)造函數(shù)和析構(gòu)函數(shù)外沒(méi)有其它成員函數(shù)。
-
它是對(duì)互斥鎖變量mutex_進(jìn)行所有權(quán)獲取,并不是每一處就重新創(chuàng)建一個(gè)鎖進(jìn)行鎖住,這樣毫無(wú)意義,因?yàn)槿绻沁@樣的話,每一個(gè)線程到了這句話的位置都會(huì)直接創(chuàng)建鎖,不會(huì)有別人來(lái)?yè)寠Z。
-
正確理解:std::lock_guard<std::mutex> locker(mutex_);是對(duì)互斥鎖變量mutex_進(jìn)行管理,在這句話后面的作用域內(nèi),代碼都處于mutex_上鎖狀態(tài),別的位置代碼獲取這個(gè)鎖mutex_會(huì)失敗。他們的目的就是為了保護(hù)同一個(gè)共享內(nèi)存區(qū)域不會(huì)被多線程同時(shí)訪問(wèn)(同時(shí)讀和寫(xiě)、或 同時(shí)寫(xiě)和寫(xiě))。
-
在std::lock_guard對(duì)象構(gòu)造時(shí),傳入的mutex對(duì)象(即它所管理的mutex對(duì)象)會(huì)被當(dāng)前線程鎖住。在lock_guard對(duì)象被析構(gòu)時(shí),它所管理的mutex對(duì)象會(huì)自動(dòng)解鎖,不需要程序員手動(dòng)調(diào)用lock和unlock對(duì)mutex進(jìn)行上鎖和解鎖操作。
-
lock_guard對(duì)象并不負(fù)責(zé)管理mutex對(duì)象的生命周期,lock_guard對(duì)象只是簡(jiǎn)化了mutex對(duì)象的上鎖和解鎖操作,方便線程對(duì)互斥量上鎖,即在某個(gè)lock_guard對(duì)象的生命周期內(nèi),它所管理的鎖對(duì)象會(huì)一直保持上鎖狀態(tài);而lock_guard的生命周期結(jié)束之后,它所管理的鎖對(duì)象會(huì)被解鎖。程序員可以非常方便地使用lock_guard,而不用擔(dān)心異常安全問(wèn)題。
std::lock_guard在構(gòu)造時(shí)只被鎖定一次,并且在銷毀時(shí)解鎖。這段話摘自C++11中std::lock_guard的使用。
C++11中std::mutex的使用.
問(wèn)題2:
std::lock_guard<std::mutex> locker(mutex_);這句話是鎖定mutex_這個(gè)互斥量,避免其他線程獲取這個(gè)互斥量嗎? 還是說(shuō),只鎖住這句話之后的代碼塊,避免別的線程訪問(wèn)該代碼塊的共享變量???
-
答:是鎖住這個(gè)互斥量。因?yàn)橐坏┯幸粋€(gè)線程的某段代碼鎖住了這個(gè)互斥量,其他線程就獲取不了這個(gè)鎖的權(quán)限了。使用同一個(gè)互斥量在不同的地方鎖住,是因?yàn)檫@幾個(gè)地方代碼肯定會(huì)訪問(wèn)同一個(gè)變量(或者說(shuō)共享內(nèi)存區(qū)域),不然不需要使用鎖。只有在多線程下才需要使用鎖。哪怕只有一個(gè)地方使用鎖,還是必要的,因?yàn)椴煌€程都在同一片代碼塊進(jìn)行寫(xiě)操作時(shí),也需要加鎖防止同時(shí)在這個(gè)地方寫(xiě)造成寫(xiě)數(shù)據(jù)混亂。
-
在代碼的多處都使用這同一句代碼std::lock_guard<std::mutex> locker(mutex_);,這些地方都爭(zhēng)搶這獲取同一個(gè)互斥量mutex_,肯定是這不同的地方都訪問(wèn)了同一片共享內(nèi)存,或者限制訪問(wèn)資源,此時(shí)只能有一塊代碼能夠獲得這個(gè)鎖,進(jìn)而只有某一時(shí)刻只有該代碼處能訪問(wèn)該資源。
-
簡(jiǎn)而言之,對(duì)于位置A和位置B對(duì)同一個(gè)互斥量mutex上鎖std::lock_guard<std::mutex> locker(mutex_);,作用就是:
-
1.同一位置A處上鎖,是防止線程1在位置A寫(xiě)的時(shí)候,線程2在位置A讀或?qū)懺搩?nèi)存區(qū)域;或者,防止線程1在位置A讀的時(shí)候,線程2在位置A寫(xiě)該內(nèi)存區(qū)域;
-
2.不同位置A和B都上鎖,是防止線程1在位置A讀的時(shí)候,線程2在位置B寫(xiě)該內(nèi)存區(qū)域,或者線程1在位置A寫(xiě)的時(shí)候,線程2在位置B讀或?qū)懺搩?nèi)存區(qū)域。
-
上面是我個(gè)人理解,如有錯(cuò)誤,望各位大佬指正。
總結(jié)
以上是生活随笔為你收集整理的【多线程】多线程锁住的是什么、std::lock_guard<std::mutex> locker(mutex_)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 【多线程】C++11进行多线程开发 (s
- 下一篇: 【多线程】std::unique_loc