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