欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

【并發(fā)編程九】c++線程同步——互斥(mutex)-創(chuàng)新互聯(lián)

【并發(fā)編程九】c++線程同步——互斥(mutex)
  • 一、互斥
    • 1、mutex
      • 1.1、mutex
      • 1.2、 lock_guard
      • 1.3、 RAII
    • 2、std::recursive_mutex
    • 3、std::shared_mutex、std::shared_lock、std::unique_lock
    • 4、std::scoped_lock
  • 二、條件變量
  • 三、future
  • 四、信號量

讓客戶滿意是我們工作的目標(biāo),不斷超越客戶的期望值來自于我們對這個(gè)行業(yè)的熱愛。我們立志把好的技術(shù)通過有效、簡單的方式提供給客戶,將通過不懈努力成為客戶在信息化領(lǐng)域值得信任、有價(jià)值的長期合作伙伴,公司提供的服務(wù)項(xiàng)目有:域名與空間、網(wǎng)站空間、營銷軟件、網(wǎng)站建設(shè)、富裕網(wǎng)站維護(hù)、網(wǎng)站推廣。
  • 簡介:
    本篇文章,我們詳細(xì)的介紹下c++標(biāo)準(zhǔn)庫提供的線程同步方法中的第一個(gè)——互斥(mutex)。
一、互斥
  • 互斥算法避免多個(gè)線程同時(shí)訪問共享資源。這會避免數(shù)據(jù)競爭,并提供線程間的同步支持。
    前四個(gè)定義于頭文件,后兩個(gè)定義于頭文件
互斥類型解釋
mutex(C++11)提供基本互斥設(shè)施(類)
timed_mutex(C++11)提供互斥設(shè)施,實(shí)現(xiàn)有時(shí)限鎖定(類)
recursive_mutex(C++11)提供能被同一線程遞歸鎖定的互斥設(shè)施(類)
recursive_timed_mutex(C++11)
提供能被同一線程遞歸鎖定的互斥設(shè)施,并實(shí)現(xiàn)有時(shí)限鎖定(類)
shared_mutex(C++17)提供共享互斥設(shè)施(類)
shared_timed_mutex(C++14)提供共享互斥設(shè)施并實(shí)現(xiàn)有時(shí)限鎖定(類)
  • 通用互斥管理
    定義于頭文件
互斥管理解釋
lock_guard(C++11)實(shí)現(xiàn)嚴(yán)格基于作用域的互斥體所有權(quán)包裝器(類模板)
scoped_lock (C++17)用于多個(gè)互斥體的免死鎖 RAII 封裝器(類模板)
unique_lock (C++11)實(shí)現(xiàn)可移動的互斥體所有權(quán)包裝器(類模板)
shared_lock(C++14)實(shí)現(xiàn)可移動的共享互斥體所有權(quán)封裝器(類模板)
defer_lock_t(C++11)
try_to_lock_t(C++11)
adopt_lock_t(C++11)
用于指定鎖定策略的標(biāo)簽類型(類)
defer_lock(C++11)
try_to_lock(C++11)
adopt_lock(C++11)
用于指定鎖定策略的標(biāo)簽常量(常量)
1、mutex 1.1、mutex
  • mutex 類是能用于保護(hù)共享數(shù)據(jù)免受從多個(gè)線程同時(shí)訪問的同步原語。
  • 通常不直接使用 std::mutex ,我們通常使用 std::unique_lock 、 std::lock_guard 或 std::scoped_lock (C++17 起)以更加異常安全的方式管理鎖定。
  • 此示例展示 mutex 能如何用于在保護(hù)共享于二個(gè)線程間的 std::map 。
  • 如果不會map加鎖,我們輸出的map中的值時(shí),可能只有一個(gè)值。
1.2、 lock_guard
  • 類 lock_guard 是互斥體包裝器,為在作用域塊期間占有互斥提供便利 RAII 風(fēng)格機(jī)制。
  • 創(chuàng)建 lock_guard 對象時(shí),它試圖接收給定互斥的所有權(quán)??刂齐x開創(chuàng)建 lock_guard 對象的作用域時(shí),銷毀lock_guard 并釋放互斥。
  • lock_guard 類不可復(fù)制。
1.3、 RAII
  • 資源獲取即初始化(Resource Acquisition Is Initialization),或稱 RAII,是一種 C++ 編程技術(shù),它將必須在使用前請求的資源(分配的堆內(nèi)存、執(zhí)行線程、打開的套接字、打開的文件、鎖定的互斥體、磁盤空間、數(shù)據(jù)庫連接等——任何存在受限供給中的事物)的生命周期綁定與一個(gè)對象的生存期相綁定。
#include#include#include#include#include#includestd::mapg_pages;
std::mutex g_pages_mutex;

void save_page(const std::string& url)
{// 模擬長頁面讀取
    std::this_thread::sleep_for(std::chrono::seconds(2));
    std::string result = "fake content";

    std::lock_guardguard(g_pages_mutex);
    g_pages[url] = result;
}

int main()
{std::thread t1(save_page, "http://foo");
    std::thread t2(save_page, "http://bar");
    t1.join();
    t2.join();

    // 現(xiàn)在訪問g_pages是安全的,因?yàn)榫€程t1/t2生命周期已結(jié)束
    for (const auto& pair : g_pages) {std::cout<< pair.first<< " =>"<< pair.second<< '\n';
    }
}

在這里插入圖片描述

2、std::recursive_mutex
  • recursive_mutex 類是同步原語,能用于保護(hù)共享數(shù)據(jù)免受從個(gè)多線程同時(shí)訪問。
  • recursive_mutex 提供排他性遞歸所有權(quán)語義:
  • recursive_mutex 的使用場景之一是保護(hù)類中的共享狀態(tài),而類的成員函數(shù)可能相互調(diào)用
  • 用法:
    recursive_mutex的用處和mutex差不多,用于限制多線程同時(shí)訪問同一個(gè)變量,用來加鎖,保證多個(gè)線程,同一時(shí)刻只能有一個(gè)線程在修改變量;和mutex不同的時(shí),recursive_mutex可以允許同一個(gè)線程遞歸的去加鎖,線程只有加鎖次數(shù)和釋放次數(shù)相同時(shí),才會釋放變量的控制權(quán);例如下面的fun2中調(diào)用了fun1,但是fun1和fun2中都加了鎖,如果使用mutex,在fun1加鎖,在fun2中再次加鎖,就會造成死鎖;所以recursive_mutex可以避免遞歸嵌套調(diào)用時(shí),造成的死鎖問題;遞歸調(diào)用不會死鎖,同一線程使用recursive_mutex加鎖次數(shù)和解鎖次數(shù)相等時(shí)釋放控制權(quán);
#include#include#includeclass X {std::recursive_mutex m;
    std::string shared;
public:
    void fun1() {std::lock_guardlk(m);
        shared = "fun1";
        std::cout<< "in fun1, shared variable is now "<< shared<< '\n';
    }
    void fun2() {std::lock_guardlk(m);
        shared = "fun2";
        std::cout<< "in fun2, shared variable is now "<< shared<< '\n';
        fun1(); // 遞歸鎖在此處變得有用
        std::cout<< "back in fun2, shared variable is "<< shared<< '\n';
    };
};

int main()
{X x;
    std::thread t1(&X::fun1, &x);
    std::thread t2(&X::fun2, &x);
    t1.join();
    t2.join();
}

在這里插入圖片描述

3、std::shared_mutex、std::shared_lock、std::unique_lock

C++17 std::shared_mutex的替代方案boost::shared_mutex
shared_mutex 類,結(jié)合 unique_lock 與 shared_lock 的使用,可以實(shí)現(xiàn)讀寫鎖。

通常讀寫鎖需要完成以下功能:

  • 1.當(dāng) data 被線程A讀取時(shí),其他線程仍可以進(jìn)行讀取卻不能寫入
  • 2.當(dāng) data 被線程A寫入時(shí),其他線程既不能讀取也不能寫入

對應(yīng)于功能1,2我們可以這樣來描述:

  • 1.當(dāng)線程A獲得共享鎖時(shí),其他線程仍可以獲得共享鎖但不能獲得獨(dú)占鎖
  • 2.當(dāng)線程A獲得獨(dú)占鎖時(shí),其他線程既不能獲得共享鎖也不能獲得獨(dú)占鎖
#include#include#includeusing namespace std;

typedef std::shared_lockread_lock;
typedef std::unique_lockwrite_lock;

std::shared_mutex read_write_mutex;
int32_t g_data =0;

//線程A,讀data
void fun1()
{for (size_t i = 0; i< 10; i++)
    {read_lock rlock(read_write_mutex);
        cout<< "t1:g_data="<< g_data<< endl;
    }
}

//線程B,讀data
void fun2()
{for (size_t i = 0; i< 10; i++)
    {read_lock rlock(read_write_mutex);
        std::cout<<"t2:g_data="<< g_data<< endl;
    }
}

//線程C,寫data
void fun3()
{for (size_t i = 0; i< 10; i++)
    {write_lock rlock(read_write_mutex);
        g_data++;
        std::cout<< "t3:g_data="<< g_data<< endl;
    }
}

int main()
{thread t3(fun3);
    thread t1(fun1);
    thread t2(fun2);
    
 
    t1.join();
    t2.join();
    t3.join();
}

輸出如下
在這里插入圖片描述

結(jié)果說明:

  • 線程1和線程2可以同時(shí)讀,
    (由于io是進(jìn)程間共享的,可以看到線程1和2同時(shí)操作時(shí),在換行endl還沒有輸出完,兩個(gè)線程出現(xiàn)了搶占io資源,所以,我們看到了t1和t2輸出到了同一行)
  • 在線程1或者線程2加了鎖讀時(shí),我們的線程3不可以寫的。(所以,我們看不到t3和t1或者t2在同一行)
  • 線程3寫入時(shí),不允許線程1和線程3寫入。(所以,我們看不到t3和t1或者t2在同一行)

簡單總結(jié)下

  • std::shared_lock是讀鎖,被鎖后仍允許其他線程執(zhí)行同樣被shared_lock的代碼,
    當(dāng)data被線程A讀取時(shí),仍允許其它線程讀取data,但是不能寫入。
  • std::unique_lock是寫鎖。被鎖后不允許其他線程執(zhí)行被shared_lock或unique_lock的代碼。
    在寫操作時(shí),一般用這個(gè),可以同時(shí)限制unique_lock的寫和share_lock的讀。
4、std::scoped_lock

lock_guard:更加靈活的鎖管理類模板,構(gòu)造時(shí)是否加鎖是可選的,在對象析構(gòu)時(shí)如果持有鎖會自動釋放鎖,所有權(quán)可以轉(zhuǎn)移。對象生命期內(nèi)允許手動加鎖和釋放鎖。

scope_lock:嚴(yán)格基于作用域(scope-based)的鎖管理類模板,構(gòu)造時(shí)是否加鎖是可選的(不加鎖時(shí)假定當(dāng)前線程已經(jīng)獲得鎖的所有權(quán)),析構(gòu)時(shí)自動釋放鎖,所有權(quán)不可轉(zhuǎn)移,對象生存期內(nèi)不允許手動加鎖和釋放鎖。

share_lock:用于管理可轉(zhuǎn)移和共享所有權(quán)的互斥對象。

  • scope_lock和lock_guard相比,可以簡單的理解,在生命周期內(nèi),scope_lock不允許手動加鎖和釋放鎖,而lock_guard可以。

參考:
1、https://www.apiref.com/cpp-zh/cpp/thread.html
2、https://en.cppreference.com/w/cpp/thread
3、書籍《c++服務(wù)器開發(fā)精髓》——張遠(yuǎn)龍

二、條件變量
  • 參見【并發(fā)編程十】c++線程同步——條件變量(condition_variable)
三、future
  • 參見【并發(fā)編程十一】c++線程同步——future
四、信號量
  • 參見【并發(fā)編程十二】c++線程同步——信號量(semaphore)

你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧

分享題目:【并發(fā)編程九】c++線程同步——互斥(mutex)-創(chuàng)新互聯(lián)
轉(zhuǎn)載注明:http://chinadenli.net/article26/ddijcg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供企業(yè)建站、商城網(wǎng)站、網(wǎng)站改版、搜索引擎優(yōu)化、虛擬主機(jī)、云服務(wù)器

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

外貿(mào)網(wǎng)站建設(shè)