最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++ 互斥鎖原理以及實(shí)際使用介紹

 更新時(shí)間:2023年04月23日 09:46:58   作者:Thomas_Lbw  
本文主要聊一聊如何使用互斥鎖以及都有哪幾種方式實(shí)現(xiàn)互斥鎖。實(shí)現(xiàn)互斥,可以有以下幾種方式:互斥量(Mutex)、遞歸互斥量(Recursive Mutex)、讀寫(xiě)鎖(Read-Write Lock)、條件變量(Condition Variable)。感興趣的同學(xué)可以參考一下

一、互斥原理(mutex)

互斥鎖可以確保在任何時(shí)候只有一個(gè)線(xiàn)程能夠進(jìn)入臨界區(qū)。當(dāng)線(xiàn)程需要進(jìn)入臨界區(qū)時(shí),它會(huì)嘗試獲取互斥鎖的所有權(quán),如果互斥鎖已經(jīng)被其他線(xiàn)程占用,那么當(dāng)前線(xiàn)程就會(huì)進(jìn)入阻塞狀態(tài),直到互斥鎖被釋放為止。簡(jiǎn)單說(shuō)就是一塊區(qū)域只能被一個(gè)線(xiàn)程執(zhí)行。

當(dāng)一個(gè)線(xiàn)程獲取到互斥鎖的所有權(quán)后,它就可以進(jìn)入臨界區(qū)進(jìn)行操作,當(dāng)操作完成后,它需要釋放互斥鎖,讓其他線(xiàn)程有機(jī)會(huì)進(jìn)入臨界區(qū)。

下面是一個(gè)簡(jiǎn)單的互斥鎖的示例代碼,它演示了如何使用 std::mutex 類(lèi)來(lái)保護(hù)臨界區(qū):

 
#include <iostream>
#include <thread>
#include <mutex>
 
// 定義互斥鎖
std::mutex g_mutex;
 
// 臨界區(qū)代碼
void critical_section(int thread_id) {
    // 加鎖
    g_mutex.lock();
    // 訪(fǎng)問(wèn)共享資源
    std::cout << "Thread " << thread_id << " enter critical section." << std::endl;
    // 釋放鎖
    std::this_thread::sleep_for(std::chrono::seconds(5));
    g_mutex.unlock();
}
 
int main() {
    // 創(chuàng)建兩個(gè)線(xiàn)程
    std::thread t1(critical_section, 1);
    std::thread t2(critical_section, 2);
    // 等待兩個(gè)線(xiàn)程執(zhí)行完成
    t1.join();
    t2.join();
    return 0;
}

main中創(chuàng)建兩個(gè)線(xiàn)程去訪(fǎng)問(wèn)資源,但是其中一個(gè)需要等待另一個(gè)線(xiàn)程5s釋放后才能訪(fǎng)問(wèn),形成對(duì)資源的鎖定。

上面的例子使用的是std::mutex實(shí)現(xiàn)互斥鎖,需要注意這個(gè)互斥鎖的聲明需要相對(duì)的全局變量,也就是說(shuō)對(duì)于使用鎖的部分它必須是“全局的”。

二、遞歸互斥量(Recursive Mutex)

C++ 中的遞歸互斥量(Recursive Mutex)是一種特殊的互斥量,它可以被同一個(gè)線(xiàn)程多次鎖定,而不會(huì)發(fā)生死鎖。遞歸互斥量的實(shí)現(xiàn)原理是,在鎖定時(shí)維護(hù)一個(gè)鎖定計(jì)數(shù)器,每次解鎖時(shí)將計(jì)數(shù)器減一,只有當(dāng)計(jì)數(shù)器為 0 時(shí)才會(huì)釋放鎖。

以下是遞歸互斥量的示例代碼:

#include <iostream>
#include <thread>
#include <mutex>
 
std::recursive_mutex mtx;
 
void foo(int n) {
    mtx.lock();
    std::cout << "Thread " << n << " locked the mutex." << std::endl;
    if (n > 1) {
        foo(n - 1);
    }
    std::cout << "Thread " << n << " unlocked the mutex." << std::endl;
    mtx.unlock();
}
 
int main() {
    std::thread t1(foo, 3);
    std::thread t2(foo, 2);
    t1.join();
    t2.join();
    return 0;
}

在上面的代碼中,我們定義了一個(gè)遞歸函數(shù) foo(),它接受一個(gè)整數(shù)參數(shù) n,表示當(dāng)前線(xiàn)程的編號(hào)。在函數(shù)中,我們首先使用遞歸互斥量 mtx 鎖定當(dāng)前線(xiàn)程,然后輸出一條帶有線(xiàn)程編號(hào)的信息,接著判斷如果 n 大于 1,則遞歸調(diào)用 foo() 函數(shù),并將參數(shù)減一。最后,我們輸出一條解鎖信息,并將遞歸互斥量解鎖。

在主函數(shù)中,我們創(chuàng)建了兩個(gè)線(xiàn)程 t1 和 t2,分別調(diào)用 foo() 函數(shù),并傳入不同的參數(shù)值。由于遞歸互斥量可以被同一個(gè)線(xiàn)程多次鎖定,因此在 t1 線(xiàn)程中對(duì) mtx 進(jìn)行了兩次鎖定,而在 t2 線(xiàn)程中只進(jìn)行了一次鎖定。

運(yùn)行結(jié)果:

可以看到,遞歸互斥量可以被同一個(gè)線(xiàn)程多次鎖定,并且在解鎖時(shí)必須對(duì)應(yīng)減少鎖定計(jì)數(shù)器。這種機(jī)制可以避免死鎖的發(fā)生,但也需要注意使用時(shí)的線(xiàn)程安全問(wèn)題。

三、讀寫(xiě)鎖(Read-Write Lock)

讀寫(xiě)鎖(Read-Write Lock)是一種特殊的互斥鎖,用于在多線(xiàn)程環(huán)境下對(duì)共享資源進(jìn)行讀寫(xiě)操作。它允許多個(gè)線(xiàn)程同時(shí)讀取共享資源,但只允許一個(gè)線(xiàn)程寫(xiě)入共享資源。讀寫(xiě)鎖的使用可以提高并發(fā)性能,特別是當(dāng)讀操作比寫(xiě)操作頻繁時(shí)。

在 C++ 中,讀寫(xiě)鎖可以通過(guò) std::shared_mutex 類(lèi)型來(lái)實(shí)現(xiàn)。下面是一個(gè)簡(jiǎn)單的示例代碼,演示了如何使用讀寫(xiě)鎖來(lái)保護(hù)一個(gè)共享的整型變量:

#include <iostream>
#include <thread>
#include <chrono>
#include <shared_mutex>
 
std::shared_mutex rw_lock; // 讀寫(xiě)鎖
int shared_var = 0; // 共享變量
 
// 寫(xiě)線(xiàn)程函數(shù)
void writer() {
    for (int i = 0; i < 10; ++i) {
        // 獨(dú)占寫(xiě)鎖
        std::unique_lock<std::shared_mutex> lock(rw_lock);
 
        // 寫(xiě)共享變量
        ++shared_var;
        std::cout << "Writer thread: write shared_var=" << shared_var << std::endl;
 
        // 等待一段時(shí)間
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
    }
}
 
// 讀線(xiàn)程函數(shù)
void reader(int id) {
    for (int i = 0; i < 10; ++i) {
        // 共享讀鎖
        std::shared_lock<std::shared_mutex> lock(rw_lock);
 
        // 讀共享變量
        int value = shared_var;
        std::cout << "Reader thread " << id << ": read shared_var=" << value << std::endl;
 
        // 等待一段時(shí)間
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
    }
}
 
int main() {
    std::thread t1(writer);
    std::thread t2(reader, 1);
    std::thread t3(reader, 2);
    std::thread t4(reader, 3);
    t1.join();
    t2.join();
    t3.join();
    t4.join();
    return 0;
}

在上面的代碼中,我們定義了一個(gè)共享變量 shared_var 和一個(gè)讀寫(xiě)鎖 rw_lock。寫(xiě)線(xiàn)程函數(shù) writer() 獨(dú)占寫(xiě)鎖,對(duì) shared_var 進(jìn)行自增操作,并輸出當(dāng)前的值。讀線(xiàn)程函數(shù) reader() 共享讀鎖,讀取 shared_var 的值,并輸出當(dāng)前的值。所有的線(xiàn)程都會(huì)等待一段時(shí)間,以模擬實(shí)際的操作。

在主函數(shù)中,我們創(chuàng)建了一個(gè)寫(xiě)線(xiàn)程和三個(gè)讀線(xiàn)程。由于讀寫(xiě)鎖的特性,讀線(xiàn)程可以并發(fā)讀取共享變量,而寫(xiě)線(xiàn)程會(huì)獨(dú)占寫(xiě)鎖,只有在寫(xiě)操作完成之后,讀線(xiàn)程才能再次讀取共享變量。因此,輸出結(jié)果中讀線(xiàn)程的順序可能會(huì)有所不同,但是寫(xiě)線(xiàn)程的操作一定是順序執(zhí)行的。

注意,這里使用 std::unique_lockstd::shared_mutex 類(lèi)型的對(duì)象來(lái)獲取獨(dú)占寫(xiě)鎖,使用 std::shared_lockstd::shared_mutex 類(lèi)型的對(duì)象來(lái)獲取共享讀鎖。這些鎖對(duì)象會(huì)在作用域結(jié)束時(shí)自動(dòng)解鎖,避免了手動(dòng)解鎖的問(wèn)題。

四、條件變量(Condition Variable)

條件變量(Condition Variable)是一種線(xiàn)程間同步機(jī)制,用于在某些特定條件下阻塞或喚醒線(xiàn)程。在 C++ 中,條件變量是通過(guò) std::condition_variable 類(lèi)來(lái)實(shí)現(xiàn)的。

下面是一個(gè)使用條件變量的示例代碼,其中有兩個(gè)線(xiàn)程,一個(gè)線(xiàn)程不停地生產(chǎn)數(shù)據(jù),另一個(gè)線(xiàn)程則等待數(shù)據(jù),當(dāng)有數(shù)據(jù)可用時(shí),將數(shù)據(jù)進(jìn)行消費(fèi)。

#include <iostream>
#include <thread>
#include <chrono>
#include <queue>
#include <mutex>
#include <condition_variable>
 
std::queue<int> data_queue; // 數(shù)據(jù)隊(duì)列
std::mutex data_mutex; // 互斥鎖
std::condition_variable data_cond; // 條件變量
 
// 生產(chǎn)數(shù)據(jù)函數(shù)
void producer() {
    for (int i = 1; i <= 10; ++i) {
        // 生產(chǎn)數(shù)據(jù)
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
        std::unique_lock<std::mutex> lock(data_mutex);
        data_queue.push(i);
        std::cout << "Producer thread: produce data " << i << std::endl;
 
        // 喚醒消費(fèi)線(xiàn)程
        data_cond.notify_one();
    }
}
 
// 消費(fèi)數(shù)據(jù)函數(shù)
void consumer() {
    while (true) {
        // 等待數(shù)據(jù)
        std::unique_lock<std::mutex> lock(data_mutex);
        data_cond.wait(lock, [] { return !data_queue.empty(); });
 
        // 消費(fèi)數(shù)據(jù)
        int data = data_queue.front();
        data_queue.pop();
        std::cout << "Consumer thread: consume data " << data << std::endl;
 
        // 檢查是否結(jié)束
        if (data == 10) {
            break;
        }
    }
}
 
int main() {
    std::thread t1(producer);
    std::thread t2(consumer);
    t1.join();
    t2.join();
    return 0;
}

在上面的代碼中,我們定義了一個(gè)數(shù)據(jù)隊(duì)列 data_queue 和一個(gè)互斥鎖 data_mutex,同時(shí)定義了一個(gè)條件變量 data_cond。生產(chǎn)數(shù)據(jù)的函數(shù) producer() 不停地往隊(duì)列中添加數(shù)據(jù),每次添加完數(shù)據(jù)之后,通過(guò)調(diào)用 data_cond.notify_one() 喚醒等待的消費(fèi)線(xiàn)程。消費(fèi)數(shù)據(jù)的函數(shù) consumer() 通過(guò)調(diào)用 data_cond.wait(lock, [] { return !data_queue.empty(); }) 來(lái)等待數(shù)據(jù),當(dāng)隊(duì)列中有數(shù)據(jù)時(shí),將數(shù)據(jù)從隊(duì)列中取出并消費(fèi),如果取出的數(shù)據(jù)是最后一個(gè),則退出循環(huán)。

在主函數(shù)中,我們創(chuàng)建了一個(gè)生產(chǎn)線(xiàn)程和一個(gè)消費(fèi)線(xiàn)程。生產(chǎn)線(xiàn)程生產(chǎn) 10 個(gè)數(shù)據(jù),消費(fèi)線(xiàn)程從隊(duì)列中消費(fèi)數(shù)據(jù),直到消費(fèi)到最后一個(gè)數(shù)據(jù)為止。

注意,這里使用了 std::unique_lockstd::mutex 類(lèi)型的對(duì)象來(lái)獲取互斥鎖,并使用 lambda 表達(dá)式 [] { return !data_queue.empty(); } 來(lái)判斷條件是否滿(mǎn)足。在調(diào)用 wait() 函數(shù)時(shí),當(dāng)前線(xiàn)程會(huì)阻塞,直到條件變量被其他線(xiàn)程喚醒或超時(shí)。當(dāng) wait() 函數(shù)返回時(shí),當(dāng)前線(xiàn)程會(huì)重新獲取互斥。

簡(jiǎn)單一些的例子:

#include <iostream>
#include <thread>
#include <chrono>
#include <mutex>
#include <condition_variable>
 
bool ready = false; // 條件變量
std::mutex data_mutex; // 互斥鎖
std::condition_variable data_cond; // 條件變量
 
void do_something() {
    // 模擬工作
    std::this_thread::sleep_for(std::chrono::milliseconds(500));
}
 
void waiting_thread() {
    // 等待條件變量
    std::unique_lock<std::mutex> lock(data_mutex);
    data_cond.wait(lock, [] { return ready; });
 
    // 條件滿(mǎn)足后輸出一句話(huà)
    std::cout << "Condition satisfied, waiting thread resumes." << std::endl;
    do_something();
}
 
int main() {
    std::thread t1(waiting_thread);
 
    // 模擬條件滿(mǎn)足后的操作
    std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    {
        std::lock_guard<std::mutex> lock(data_mutex);
        ready = true;
        data_cond.notify_one();
    }
 
    t1.join();
    return 0;
}

在上面的代碼中,我們定義了一個(gè)條件變量 ready 和一個(gè)互斥鎖 data_mutex,同時(shí)定義了一個(gè)條件變量 data_cond。等待條件變量的函數(shù) waiting_thread() 首先獲取互斥鎖,然后通過(guò)調(diào)用 data_cond.wait(lock, [] { return ready; }) 等待條件變量,當(dāng) ready 為 true 時(shí),線(xiàn)程會(huì)被喚醒,輸出一句話(huà),并模擬一些工作的操作。在主函數(shù)中,我們創(chuàng)建了一個(gè)等待條件變量的線(xiàn)程 t1,然后模擬條件滿(mǎn)足后的操作,即將 ready 設(shè)置為 true,然后通過(guò)調(diào)用 data_cond.notify_one() 喚醒等待的線(xiàn)程。 

五、總結(jié)

互斥鎖保證了計(jì)算機(jī)資源訪(fǎng)問(wèn)的安全,互斥鎖的不當(dāng)使用同時(shí)也加大了程序阻塞的風(fēng)險(xiǎn)。

提前祝大家五一前工作生活學(xué)習(xí)一切順利。

到此這篇關(guān)于C++ 互斥鎖原理以及實(shí)際使用介紹的文章就介紹到這了,更多相關(guān)C++ 互斥鎖原理及使用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C/C++的全緩沖、行緩沖和無(wú)緩沖

    C/C++的全緩沖、行緩沖和無(wú)緩沖

    這篇文章主要介紹了C/C++的全緩沖、行緩沖和無(wú)緩沖的相關(guān)知識(shí),幫助大家更好的理解和學(xué)習(xí)c/c++,感興趣的朋友可以了解下
    2020-08-08
  • C++使用sort對(duì)容器排序的實(shí)現(xiàn)

    C++使用sort對(duì)容器排序的實(shí)現(xiàn)

    C++ STL 標(biāo)準(zhǔn)庫(kù)中的sort()函數(shù)專(zhuān)門(mén)用來(lái)對(duì)容器或普通數(shù)組中指定范圍內(nèi)的元素進(jìn)行排序,本文就詳細(xì)的介紹一下怎么實(shí)現(xiàn),需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-05-05
  • C語(yǔ)言報(bào)錯(cuò)Use of Uninitialized Variable的原因及解決方案

    C語(yǔ)言報(bào)錯(cuò)Use of Uninitialized Variable的原因及解決方案

    Use of Uninitialized Variable是C語(yǔ)言中常見(jiàn)且危險(xiǎn)的錯(cuò)誤之一,它通常在程序試圖使用一個(gè)未初始化的變量時(shí)發(fā)生,本文將詳細(xì)介紹Use of Uninitialized Variable的產(chǎn)生原因,提供多種解決方案,并通過(guò)實(shí)例代碼演示如何有效避免和解決此類(lèi)錯(cuò)誤,需要的朋友可以參考下
    2024-06-06
  • C++?使用?new?創(chuàng)建二維數(shù)組實(shí)例

    C++?使用?new?創(chuàng)建二維數(shù)組實(shí)例

    這篇文章主要介紹了C++?使用?new?創(chuàng)建二維數(shù)組實(shí)例的相關(guān)資料,需要的朋友可以參考下
    2023-01-01
  • C語(yǔ)言中的編碼小技巧

    C語(yǔ)言中的編碼小技巧

    這篇文章主要介紹了C語(yǔ)言中的編碼小技巧,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • C++實(shí)現(xiàn)圖書(shū)管理系統(tǒng)

    C++實(shí)現(xiàn)圖書(shū)管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)圖書(shū)管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-12-12
  • c++ 實(shí)現(xiàn)文件逐行讀取與字符匹配

    c++ 實(shí)現(xiàn)文件逐行讀取與字符匹配

    這里嘗試通過(guò)C++來(lái)實(shí)現(xiàn)一個(gè)文件IO的功能,看看是否能夠比python的表現(xiàn)更好一些,感興趣的朋友可以參考下
    2021-05-05
  • C++中vector容器的常用操作方法實(shí)例總結(jié)

    C++中vector容器的常用操作方法實(shí)例總結(jié)

    vector容器一般被用作創(chuàng)建動(dòng)態(tài)數(shù)組,動(dòng)態(tài)數(shù)組就像Python中的list結(jié)構(gòu)一樣,可以比普通數(shù)組擁有更豐富操作方法,下面就為大家整理了一些最常用的操作:
    2016-05-05
  • 使用c++實(shí)現(xiàn)OpenCV圖像橫向&縱向拼接

    使用c++實(shí)現(xiàn)OpenCV圖像橫向&縱向拼接

    這篇文章主要介紹了使用c++實(shí)現(xiàn)OpenCV圖像橫向&縱向拼接,文中有圖像拼接函數(shù),可以實(shí)現(xiàn)如“長(zhǎng)圖拼接王”這類(lèi)小程序的類(lèi)似功能,大家可以將該函數(shù)封裝在軟件中自由使用
    2021-08-08
  • C++訪(fǎng)問(wèn)者模式模板函數(shù)無(wú)法重載的問(wèn)題解決

    C++訪(fǎng)問(wèn)者模式模板函數(shù)無(wú)法重載的問(wèn)題解決

    本文主要介紹了C++訪(fǎng)問(wèn)者模式模板函數(shù)無(wú)法重載的問(wèn)題解決,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-12-12

最新評(píng)論

保德县| 汾阳市| 伊通| 石河子市| 营山县| 彭州市| 郓城县| 青川县| 北安市| 临湘市| 南部县| 离岛区| 财经| 额尔古纳市| 清水县| 南安市| 阳东县| 苍梧县| 陇川县| 南江县| 息烽县| 宜昌市| 富裕县| 镇赉县| 边坝县| 宜川县| 金阳县| 虎林市| 双柏县| 怀集县| 讷河市| 乐山市| 台东市| 河东区| 云南省| 大余县| 平乡县| 杂多县| 保康县| 连州市| 尼勒克县|