欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++多線程之unique_lock的使用詳解

 更新時(shí)間:2025年04月03日 09:25:18   作者:今夜有雨.  
本文主要介紹了C++多線程之unique_lock的使用詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

一、為什么會有unique_lock?

因?yàn)閙utex再管理方面有瑕疵,因此出現(xiàn)了一個(gè)互斥量封裝器lock_guard來智能的管理mutex。但是lock_guard只是簡單的管理,功能比較弱,有瑕疵。因此需要搞出來一個(gè)功能更強(qiáng)大的東西出來,而這個(gè)東西就是unique_lock。
本質(zhì)上來說lock_guard和unique_lock都是為了更好地使用各種鎖而誕生的,但是unique_lock更為靈活,功能更強(qiáng)大,可做的操作比較多。

unique_lock 有些時(shí)候也被稱為“靈活鎖”

二、std::lock_guard可能存在的問題

序號問題描述細(xì)節(jié)
1鎖的粒度問題std::lock_guard的鎖作用域與對象的作用域相同,可能導(dǎo)致鎖的粒度過大,影響并發(fā)性能。
2無法中途解鎖一旦std::lock_guard對象構(gòu)造,鎖將被自動獲取,并在對象析構(gòu)時(shí)自動釋放,無法中途手動解鎖
3不支持條件變量std::lock_guard通常與互斥鎖一起使用,但不支持與條件變量一起使用(如std::condition_variable)配合使用。
4不支持遞歸鎖雖然可以與std::recursive_mutex一起使用,但std::lock_guard本身不提供對遞歸鎖的特殊支持
5無法指定鎖的嘗試獲取std::lock_guard總是嘗試獲取鎖,不支持非阻塞(嘗試)獲取鎖
6無法與超時(shí)機(jī)制結(jié)合std::guard不提供超時(shí)機(jī)制,無法設(shè)置獲取鎖的等待時(shí)間

三、什么是unique_lock?

unique_lock是一個(gè)更靈活的互斥量封裝器,它提供了更多的控制選項(xiàng),比如延遲鎖定、嘗試鎖、遞歸鎖定、定時(shí)鎖定等。于std::lock_guard相比,std::unique_lock提供了更多的功能,但也需要更多的管理責(zé)任。

如何定義使用unique_lock?

unique_lock的構(gòu)造

std::mutex mtx;
std::unique_lock <std::mutex> lck1(mtx);//自動上鎖
//自動鎖定
std::unique_lock <std::mutex> lck2(mtx, std::defer_lock);//延遲鎖定
std::unique_lock <std::mutex> lck3(mtx, std::adopt_lock);//接受已鎖定的mutex,不允許再次鎖定
std::unique_lock <std::mutex> lck4(mtx, std::try_to_lock);//嘗試鎖定

std::defer_lock的具體含義是告訴std::unique_lock在構(gòu)造時(shí)不要自動鎖定互斥鎖,而是延遲鎖定操作
std::unique_lock提供了一些成員函數(shù),用于管理鎖定狀態(tài)
lock()鎖定關(guān)聯(lián)的mutex
unlock()解鎖關(guān)聯(lián)的mutex
try_lock()嘗試鎖定mutex,如果鎖定成功,返回true,否則返回false
owns_lock()返回一個(gè)布爾值,指示unique_lock是否擁有mutex的所有權(quán)

unique_lock的第二個(gè)參數(shù)

std::unique_lock的構(gòu)造函數(shù)可以接受多個(gè)參數(shù),其中第二個(gè)參數(shù)用于指定如何管理鎖的行為。常見的第二個(gè)參數(shù)有以下幾種:

  • std::defer_lock
  • std::try_to_lock
  • std::adopt_lock
  • 超時(shí)相關(guān)參數(shù)(如std::chrono的時(shí)間段)

接下來我們依次用代碼例子來看

  • std::defer_lock
    std::defer_lock表示延遲鎖定。即在創(chuàng)建std::unique_lock對象時(shí),不會立即對互斥鎖進(jìn)行鎖定操作。
#include <iostream>
#include <thread>
#include <mutex>
using namespace std;

mutex mtx;
void example_defer_lock()
{
    unique_lock<mutex> lock(mtx,std::defer_lock);//不會立即鎖定
    lock.lock();//在需要時(shí)顯式鎖定
    for(int i=0;i<5;i++)
    {
        cout<<"Thread : "<<this_thread::get_id()<<" : "<<i<<endl;
    }
    
    cout<<"Locked with defer_lock"<<endl;
    lock.unlock();//顯式解鎖
}

int main()
{
    thread t1(example_defer_lock);
    t1.join();

    return 0;
}

這段代碼主要展示了如何使用 unique_lock 結(jié)合 defer_lock 策略進(jìn)行互斥鎖的操作。通過使用
defer_lock,程序可以將鎖的鎖定操作延遲到需要的時(shí)候,這在某些情況下非常有用,例如在進(jìn)行一些準(zhǔn)備工作后再進(jìn)行鎖定,或者根據(jù)條件判斷是否需要鎖定。同時(shí),使用
unique_lock 可以自動管理鎖的生命周期,避免忘記解鎖而導(dǎo)致的死鎖問題,而顯式的 lock 和 unlock
操作則提供了更靈活的控制方式,允許程序在鎖定和解鎖的時(shí)機(jī)上有更多的選擇。在 example_defer_lock 函數(shù)中,先創(chuàng)建
unique_lock 但不鎖定,之后根據(jù)需要進(jìn)行鎖定,在完成一些操作后解鎖,保證資源的正確訪問和釋放,確保線程安全。

  • std::try_to_lock
    std::try_to_lock表示嘗試鎖定。在創(chuàng)建std::unique_lock對象時(shí),會嘗試鎖定互斥鎖。如果鎖定失敗,不會阻塞。
#include <iostream>
#include <thread>
#include <mutex>
using namespace std;

mutex mtx;

void example_try_lock()
{
    unique_lock<mutex> lck(mtx, try_to_lock);//嘗試鎖定
    if (lck.owns_lock())
    {
        cout <<this_thread::get_id() <<" I have the lock\n" << endl;
    }
    else
    {
        cout <<""<<this_thread::get_id()<< " I don't have the lock\n" << endl;
    }
}
int main()
{
    // 創(chuàng)建兩個(gè)線程
    thread t1(example_try_lock);//線程一鎖定么互斥量
    thread t2(example_try_lock);//線程二嘗試鎖定么互斥量,但是因?yàn)楸痪€程一占用著,所以沒有鎖定成功
    t1.join();
    t2.join();

    return 0;
}

在這里插入圖片描述

這段代碼主要展示了如何使用 unique_lock 的 try_to_lock
特性來嘗試鎖定互斥鎖,并且根據(jù)鎖定結(jié)果進(jìn)行不同的處理。它創(chuàng)建了兩個(gè)線程 t1 和 t2,這兩個(gè)線程會嘗試鎖定同一個(gè)互斥鎖
mtx。由于互斥鎖的特性,只有一個(gè)線程能夠成功鎖定,另一個(gè)線程將無法鎖定。通過 owns_lock
方法可以判斷線程是否成功獲取到鎖,并輸出相應(yīng)的信息。這種方式可以避免線程阻塞,而是讓線程在無法獲取鎖時(shí)繼續(xù)執(zhí)行其他任務(wù)或采取其他處理方式。同時(shí),unique_lock
會在析構(gòu)時(shí)自動解鎖,避免了手動解鎖的繁瑣操作。
這種機(jī)制在多線程編程中非常有用,特別是當(dāng)線程需要嘗試獲取資源,但不希望在獲取不到時(shí)阻塞等待的情況,允許線程在不阻塞的情況下執(zhí)行其他任務(wù),提高程序的響應(yīng)性和資源利用率。

  • std::adopt_lock

std::adopt_lock表示接管已經(jīng)鎖定的互斥鎖。此參數(shù)假設(shè)互斥鎖已經(jīng)在其他地方被鎖定,std::unique_lock對象會接管這個(gè)鎖的所有權(quán)。使用了std::adopt_lock,這意味著互斥鎖已經(jīng)被鎖定。

#include <iostream>
#include <thread>
#include <mutex>
using namespace std;

mutex mtx;

void example_adopt_lock()
{
    mtx.lock();//先鎖定互斥鎖
    unique_lock<mutex> lock(mtx, adopt_lock);//接管已鎖定的鎖
    cout<<"Locked with adopt_lock"<<endl;
    //mtx.unlock();

}

int main()
{
    thread t1(example_adopt_lock);
    t1.join();

    return 0;
}

總體來說,這段代碼的目的是展示如何在已經(jīng)手動鎖定互斥鎖的情況下,使用 std::unique_lock 結(jié)合 adopt_lock 來管理該互斥鎖,從而簡化鎖的管理并確保在適當(dāng)?shù)臅r(shí)候自動解鎖。

總結(jié)

unique_lock的特點(diǎn)

  • 靈活性:unique_lock提供了更多的控制選項(xiàng),比如延遲鎖定、嘗試鎖定、遞歸鎖定、定時(shí)鎖定等。這使得開發(fā)者可以根據(jù)具體的業(yè)務(wù)邏輯來精確控制鎖的加鎖和解鎖時(shí)機(jī)。
  • 可移動性:unique_lock是可移動的,可以拷貝、賦值或移動。這使得開發(fā)者可以在需要時(shí)輕松的將鎖的所有權(quán)從一個(gè)對象轉(zhuǎn)移到另一個(gè)對象。
  • 手動控制:unique_lock支持手動解鎖,而lock_guard不支持。這提供了更大的靈活性,但也需要開發(fā)者自行管理鎖的加鎖和解鎖過程。

到此這篇關(guān)于C++多線程之unique_lock的使用詳解的文章就介紹到這了,更多相關(guān)C++ unique_lock內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家! 

相關(guān)文章

  • C語言怎么獲得進(jìn)程的PE文件信息

    C語言怎么獲得進(jìn)程的PE文件信息

    這篇文章主要介紹了C語言怎么獲得進(jìn)程的PE文件信息的相關(guān)代碼,需要的朋友可以參考下
    2016-01-01
  • MFC之ComboBox控件用法實(shí)例教程

    MFC之ComboBox控件用法實(shí)例教程

    這篇文章主要介紹了MFC之ComboBox控件用法,包括了ComboBox控件常見的各類用法,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2014-09-09
  • C++基礎(chǔ)學(xué)習(xí)之輸入輸出流詳解

    C++基礎(chǔ)學(xué)習(xí)之輸入輸出流詳解

    C++是一種廣泛應(yīng)用的編程語言,其輸入和輸出是程序所必須的基本操作之一。本文將介紹C++中的輸入和輸出操作,包括輸入輸出流、文件輸入輸出等,希望對讀者有所幫助
    2023-04-04
  • c實(shí)現(xiàn)linux下的數(shù)據(jù)庫備份

    c實(shí)現(xiàn)linux下的數(shù)據(jù)庫備份

    本文給大家簡單介紹下c實(shí)現(xiàn)linux下的數(shù)據(jù)庫備份的方法和具體的源碼,十分的實(shí)用,有需要的小伙伴可以參考下。
    2015-07-07
  • C++ Boost log日志庫超詳細(xì)講解

    C++ Boost log日志庫超詳細(xì)講解

    Boost是為C++語言標(biāo)準(zhǔn)庫提供擴(kuò)展的一些C++程序庫的總稱。Boost庫是一個(gè)可移植、提供源代碼的C++庫,作為標(biāo)準(zhǔn)庫的后備,是C++標(biāo)準(zhǔn)化進(jìn)程的開發(fā)引擎之一,是為C++語言標(biāo)準(zhǔn)庫提供擴(kuò)展的一些C++程序庫的總稱
    2022-11-11
  • opencv實(shí)現(xiàn)圖形輪廓檢測

    opencv實(shí)現(xiàn)圖形輪廓檢測

    這篇文章主要為大家詳細(xì)介紹了opencv實(shí)現(xiàn)圖形輪廓檢測,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-04-04
  • 一起來看看C++STL容器之string類

    一起來看看C++STL容器之string類

    這篇文章主要為大家詳細(xì)介紹了C++STL容器之string類,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-03-03
  • C++深入講解new與deleted關(guān)鍵字的使用

    C++深入講解new與deleted關(guān)鍵字的使用

    這篇文章主要介紹了C++中new與deleted關(guān)鍵字的使用,new在動態(tài)內(nèi)存中為對象分配空間并返回一個(gè)指向該對象的指針;delete接受一個(gè)動態(tài)對象的指針, 銷毀該對象, 并釋放與之關(guān)聯(lián)的內(nèi)存
    2022-05-05
  • C語言示例講解do?while循環(huán)語句的用法

    C語言示例講解do?while循環(huán)語句的用法

    在不少實(shí)際問題中有許多具有規(guī)律性的重復(fù)操作,因此在程序中就需要重復(fù)執(zhí)行某些語句。一組被重復(fù)執(zhí)行的語句稱之為循環(huán)體,能否繼續(xù)重復(fù),決定循環(huán)的終止條件
    2022-06-06
  • 枚舉類型的定義和應(yīng)用總結(jié)

    枚舉類型的定義和應(yīng)用總結(jié)

    如果一種變量只有幾種可能的值,可以定義為枚舉類型。所謂“枚舉類型”是將變量的值一一列舉出來,變量的值只能在列舉出來的值的范圍內(nèi)
    2013-10-10

最新評論