91欧美超碰AV自拍|国产成年人性爱视频免费看|亚洲 日韩 欧美一厂二区入|人人看人人爽人人操aV|丝袜美腿视频一区二区在线看|人人操人人爽人人爱|婷婷五月天超碰|97色色欧美亚州A√|另类A√无码精品一级av|欧美特级日韩特级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

深入了解互斥鎖、條件變量、讀寫鎖以及自旋鎖

Linux愛好者 ? 來源:果凍蝦仁 ? 作者:果凍蝦仁 ? 2021-11-01 10:02 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

鎖是一個常見的同步概念,我們都聽說過加鎖(lock)或者解鎖(unlock),當(dāng)然學(xué)術(shù)一點的說法是獲?。?a target="_blank">acquire)和釋放(release)。

恰好pthread包含這幾種鎖的API,而C++11只包含其中的部分。接下來我主要通過pthread的API來展開本文。

mutex(互斥量)

mutex(mutual exclusive)即互斥量(互斥體)。也便是常說的互斥鎖。

盡管名稱不含lock,但是稱之為鎖,也是沒有太大問題的。mutex無疑是最常見的多線程同步方式。其思想簡單粗暴,多線程共享一個互斥量,然后線程之間去競爭。得到鎖的線程可以進(jìn)入臨界區(qū)執(zhí)行代碼。

//聲明一個互斥量
pthread_mutex_tmtx;
//初始化
pthread_mutex_init(&mtx,NULL);
//加鎖
pthread_mutex_lock(&mtx);
//解鎖
pthread_mutex_unlock(&mtx);
//銷毀
pthread_mutex_destroy(&mtx);

mutex是睡眠等待(sleep waiting)類型的鎖,當(dāng)線程搶互斥鎖失敗的時候,線程會陷入休眠。優(yōu)點就是節(jié)省CPU資源,缺點就是休眠喚醒會消耗一點時間。另外自從Linux 2.6版以后,mutex完全用futex的API實現(xiàn)了,內(nèi)部系統(tǒng)調(diào)用的開銷大大減小。

值得一提的是,pthread的鎖一般都有一個trylock的函數(shù),比如對于互斥量:

ret=pthread_mutex_trylock(&mtx);
if(0==ret){//加鎖成功
...
pthread_mutex_unlock(&mtx);
}elseif(EBUSY==ret){//鎖正在被使用;
...
}

pthread_mutex_trylock用于以非阻塞的模式來請求互斥量。就好比各種IO函數(shù)都有一個noblock的模式一樣,對于加鎖這件事也有類似的非阻塞模式。

當(dāng)線程嘗試加鎖時,如果鎖已經(jīng)被其他線程鎖定,該線程就會阻塞住,直到能成功acquire。但有時候我們不希望這樣。

pthread_mutex_trylock在被其他線程鎖定時,會返回特殊錯誤碼。加鎖成返回0,僅當(dāng)成功但時候,我們才能解鎖在后面進(jìn)行解鎖操作!

C++11開始引入了多線程庫,其中也包含了互斥鎖的API:std::muxtex 。

此外,依據(jù)同一線程是否能多次加鎖,把互斥量又分為如下兩類:

  • 是:稱為『遞歸互斥量』recursive mutex ,也稱『可重入鎖』reentrant lock
  • 否:即『非遞歸互斥量』non-recursive mute),也稱『不可重入鎖』non-reentrant mutex

若同一線程對非遞歸的互斥量多次加鎖,可能會造成死鎖。遞歸互斥量則無此風(fēng)險。C++11中有遞歸互斥量的API:std::recursive_mutex。對于pthread則可以通過給mutex添加PTHREAD_MUTEX_RECURSIVE 屬性的方式來使用遞歸互斥量:

//聲明一個互斥量
pthread_mutex_tmtx;
//聲明一個互斥量的屬性變量
pthread_mutexattr_tmtx_attr;

//初始化互斥量的屬性變量
pthread_mutexattr_init(&mtx_attr);
//設(shè)置遞歸互斥量的屬性
pthread_mutexattr_settype(&mtx_attr,PTHREAD_MUTEX_RECURSIVE);

//把屬性賦值給互斥量
pthread_mutext_init(&mtx,&mutext_attr);

然而對于遞歸互斥量或者說可重入鎖的使用則需要克制。Stevens大神生前在《APUE》中說『使用好它是十分tricky的,僅當(dāng)沒有其他解決方案時才使用』。

可重入鎖這個概念和稱呼的走俏多半是Java語言的功勞。

condition variable(條件變量)

請注意條件變量不是鎖,它是一種線程間的通訊機制,并且?guī)缀蹩偸呛突コ饬恳黄鹗褂玫?。所以互斥量和條件變量二者一般是成套出現(xiàn)的。比如C++11中也有條件變量的API:std::condition_variable

對于pthread:

//聲明一個互斥量
pthread_mutex_tmtx;
//聲明一個條件變量
pthread_cond_tcond;
...

//初始化
pthread_mutex_init(&mtx,NULL);
pthread_cond_init(&cond,NULL);

//加鎖
pthread_mutex_lock(&mtx);
//加鎖成功,等待條件變量觸發(fā)
pthread_cond_wait(&cond,&mtx);

...
//加鎖
pthread_mutex_lock(&mtx);
pthread_cond_signal(&cond);
...
//解鎖
pthread_mutex_unlock(&mtx);
//銷毀
pthread_mutex_destroy(&mtx)

pthread_cond_wait函數(shù)會把條件變量和互斥量都傳入。并且多線程調(diào)用的時候條件變量和互斥量一定要一一對應(yīng),不能一個條件變量在不同線程中wait的時候傳入不同的互斥量。否則是未定義結(jié)果。

關(guān)于是先解鎖互斥量還是先進(jìn)行條件變量的通知,是另外一個比較大的議題。有種論斷說:先解鎖互斥量再通知條件變量可以減少多余的上下文切換,進(jìn)而提高效率。這種說法是基于一種實現(xiàn)假設(shè):先通知條件變量,再解鎖。

可能讓其他等待條件變量的線程被喚醒了,但是此時互斥量還沒解鎖,從而再次陷入休眠。然而對于另外一些實現(xiàn),比如Linux系統(tǒng),則通過等待變形(wait morphing)解決了這一問題。所以先通知再解鎖也沒用問題。

另外在使用條件變量的過程中有個稍微違反直覺的寫法:那就是使用while而不是if來做判斷狀態(tài)是否滿足。這樣做的原因有二:

  1. 避免驚群;
  2. 避免某些情況下線程被虛假喚醒(即沒有pthread_cond_signal就解除了阻塞)。

比如半同步/半reactor的網(wǎng)絡(luò)模型中,在工作線程消費fd隊列的時候:

while(1){
if(pthread_mutex_lock(&mtx)!=0){//加鎖
...//異常邏輯
}
while(!queue.empty()){
if(pthread_cond_wait(&cond,&mtx)!=0){
...//異常邏輯
}
}
autodata=queue.pop();
if(pthread_mutex_unlock(&mtx)!=0){//解鎖
...//異常邏輯
}
process(data);//處理流程,業(yè)務(wù)邏輯
}

read-write lock(讀寫鎖)

顧名思義『讀寫鎖』就是對于臨界區(qū)區(qū)分讀和寫。在讀多寫少的場景下,不加區(qū)分的使用互斥量顯然是有點浪費的。此時便該上演讀寫鎖的拿手好戲。

讀寫鎖有一個別稱叫『共享-獨占鎖』。不過單看『共享-獨占鎖』或者『讀寫鎖』這兩個名稱,其實并未區(qū)分對于讀和寫,到底誰共享,誰獨占??赡軙屓苏`以為讀寫鎖是一種更為泛化的稱呼,其實不是。讀寫鎖的含義是準(zhǔn)確的:是一種 讀共享,寫?yīng)氄嫉逆i。

讀寫鎖的特性:

  • 當(dāng)讀寫鎖被加了寫鎖時,其他線程對該鎖加讀鎖或者寫鎖都會阻塞(不是失敗)。
  • 當(dāng)讀寫鎖被加了讀鎖時,其他線程對該鎖加寫鎖會阻塞,加讀鎖會成功。

因而適用于多讀少寫的場景。

//聲明一個讀寫鎖
pthread_rwlock_trwlock;
...
//在讀之前加讀鎖
pthread_rwlock_rdlock(&rwlock);

...共享資源的讀操作

//讀完釋放鎖
pthread_rwlock_unlock(&rwlock);

//在寫之前加寫鎖
pthread_rwlock_wrlock(&rwlock);

...共享資源的寫操作

//寫完釋放鎖
pthread_rwlock_unlock(&rwlock);

//銷毀讀寫鎖
pthread_rwlock_destroy(&rwlock);

其實加讀鎖和加寫鎖這兩個說法可能會造成誤導(dǎo),讓人誤以為是有兩把鎖,其實讀寫鎖是一個鎖。所謂加讀鎖和加寫鎖,準(zhǔn)確的說法可能是『給讀寫鎖加讀模式的鎖定和加寫模式的鎖定』。

讀寫鎖和互斥量一樣也有trylock函數(shù),也是以非阻塞地形式來請求鎖,不會導(dǎo)致阻塞。

pthread_rwlock_tryrdlock(&rwlock)
pthread_rwlock_trywrlock(&rwlock)

C++11中有互斥量、條件變量但是并沒有引入讀寫鎖。而在C++17中出現(xiàn)了一種新鎖:std::shared_mutex。用它可以模擬實現(xiàn)出讀寫鎖。demo代碼可以直接參考cppreference:

https://en.cppreference.com/w/cpp/thread/shared_mutex

另外多讀少寫的場景有些特殊場景,可以用特殊的數(shù)據(jù)結(jié)構(gòu)減少鎖使用:

  • 多讀單寫的線性數(shù)據(jù)。用數(shù)組實現(xiàn)環(huán)形隊列,避免vector等動態(tài)擴張的數(shù)據(jù)結(jié)構(gòu),寫在結(jié)尾,由于單寫因而可以不加鎖;讀在開頭,由于多讀(避免重復(fù)消費)所以需要加一下鎖(互斥量就行)。
  • 多讀單寫的KV??梢允褂秒p緩沖(double buffer)的數(shù)據(jù)結(jié)構(gòu)來實現(xiàn)。double buffer同名的概念比較多,這里指的是foreground 和 backgroud 兩個buffer進(jìn)行切換的『0 - 1切換』技術(shù)。比如實現(xiàn)動態(tài)加載(熱加載)配置文件的時候??赡軙谇袚Q間隙加一個短暫的互斥量,但是基本可以認(rèn)為是lock free的。

我一張口,你就會發(fā)現(xiàn):無非是空間換時間的老套路了。

spinlock(自旋鎖)

自旋之名頗為玄妙,第一次聽聞常讓人略覺高大。但和無數(shù)個好似『故意把簡單概念復(fù)雜化』的計算機術(shù)語一樣,自旋鎖的本質(zhì)簡單的難以置信。

要了解自旋鎖,首先了解自旋。什么是自旋(spin)呢?更為通俗的一個詞是『忙等待』(busy waiting)。最最通俗的一個理解,其實就是死循環(huán)……。

單看使用方法和使用互斥量的代碼是差不多的。只不過自旋鎖不會引起線程休眠。當(dāng)共享資源的狀態(tài)不滿足的時候,自旋鎖會不停地循環(huán)檢測狀態(tài)。因為不會陷入休眠,而是忙等待的方式也就不需要條件變量。

這是優(yōu)點也是缺點。不休眠就不會引起上下文切換,但是會比較浪費CPU。

//聲明一個自旋鎖變量
pthread_spinlock_tspinlock;

//初始化
pthread_spin_init(&spinlock,0);

//加鎖
pthread_spin_lock(&spinlock);

//解鎖
pthread_spin_unlock(&spinlock);

//銷毀
pthread_spin_destroy(&spinlock);

pthread_spin_init函數(shù)的第二個參數(shù)名為pshared(int類型)。表示的是是否能進(jìn)程間共享自旋鎖。這被稱之為Thread Process-Shared Synchronization?;コ饬康耐ㄟ^屬性也可以把互斥量設(shè)置成進(jìn)程間共享的。pshared有兩個枚舉值:

  • PTHREAD_PROCESS_PRIVATE:僅同進(jìn)程下讀線程可以使用該自旋鎖
  • PTHREAD_PROCESS_SHARED:不同進(jìn)程下的線程可以使用該自旋鎖

Linux上的glibc中這兩個枚舉值分別是01Mac上不是)。所以通常也會看到直接傳0的代碼。你可能覺得不使用宏,直接用數(shù)字硬編碼不是一個好習(xí)慣。的確,妥妥的Magic Number,但還有一個有趣的事實你需要了解:并不是所有實現(xiàn)都支持自旋鎖設(shè)置pshared。比如:

intpthread_spin_init(pthread_spinlock_t*lock,intpshared){
/*RelaxedMOisfinebecausethisisaninitializingstore.*/
atomic_store_relaxed(lock,0);
return0;
}

所以直接傳0可能也無傷大雅。

自旋鎖 VS 互斥量+條件變量 孰優(yōu)孰劣?肯定要看具體的使用場景,(我好像在說片湯話)。當(dāng)你不知道在你的使用場景下這兩種鎖該用哪個的時候,那就是用互斥量吧!

或者通過壓測的判斷,不過大多數(shù)時候我們好像并不需要這么一個pthread的自旋鎖,知友們可以提供一些自旋鎖的使用參考。

編輯:jq
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • cpu
    cpu
    +關(guān)注

    關(guān)注

    68

    文章

    11277

    瀏覽量

    224944
  • 數(shù)據(jù)
    +關(guān)注

    關(guān)注

    8

    文章

    7335

    瀏覽量

    94754
  • Mac
    Mac
    +關(guān)注

    關(guān)注

    0

    文章

    1127

    瀏覽量

    55309
  • 函數(shù)
    +關(guān)注

    關(guān)注

    3

    文章

    4417

    瀏覽量

    67499

原文標(biāo)題:如何理解互斥鎖、條件變量、讀寫鎖以及自旋鎖?

文章出處:【微信號:LinuxHub,微信公眾號:Linux愛好者】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關(guān)推薦
    熱點推薦

    探索TMAG5115:高性能霍爾效應(yīng)存器的卓越特性與應(yīng)用

    探索TMAG5115:高性能霍爾效應(yīng)存器的卓越特性與應(yīng)用 在電子工程師的日常設(shè)計中,傳感器的選擇至關(guān)重要,它直接影響著系統(tǒng)的性能和穩(wěn)定性。今天,我們就來深入了解一款高性能的霍爾效應(yīng)存器
    的頭像 發(fā)表于 02-11 11:40 ?254次閱讀

    面試必看!排隊自旋32位變量的域劃分與核心作用

    在操作系統(tǒng)面試中,并發(fā)同步機制一直是高頻考點,而排隊自旋作為解決傳統(tǒng)自旋“饑餓” 問題的關(guān)鍵技術(shù),其 32 位變量的域劃分更是面試官青睞
    的頭像 發(fā)表于 02-09 16:54 ?806次閱讀
    面試必看!排隊<b class='flag-5'>自旋</b><b class='flag-5'>鎖</b>32位<b class='flag-5'>變量</b>的域劃分與核心作用

    面試必看:排隊自旋之MCS的實現(xiàn)原理與關(guān)鍵考點

    在并發(fā)編程面試中,“” 是繞不開的核心話題,而自旋作為輕量級的代表,其優(yōu)化方案更是高頻考點。
    的頭像 發(fā)表于 02-09 16:51 ?745次閱讀
    面試必看:排隊<b class='flag-5'>自旋</b><b class='flag-5'>鎖</b>之MCS<b class='flag-5'>鎖</b>的實現(xiàn)原理與關(guān)鍵考點

    深入解析CD4514B與CD4515B:4位存/4到16線解碼器

    )的CD4514B和CD4515B這兩款CMOS 4位存/4到16線解碼器,了解它們的特性、參數(shù)、應(yīng)用以及設(shè)計要點。 文件下載: cd4515b.pdf 產(chǎn)品概述 CD4514B和CD4515B由一個4位選
    的頭像 發(fā)表于 01-16 14:25 ?267次閱讀

    【「Linux 設(shè)備驅(qū)動開發(fā)(第 2 版)」閱讀體驗】Linux內(nèi)核開發(fā)基礎(chǔ)

    時,必須對其進(jìn)行同步,以確保只有允許訪問的競爭者才能擁有該資源。以下是兩種同步機制: :用于互斥。當(dāng)一個競爭者持有時,其他競爭者不能持有 條件
    發(fā)表于 01-12 22:45

    【「Linux 設(shè)備驅(qū)動開發(fā)(第 2 版)」閱讀體驗】+讀內(nèi)核處理的核心輔助函數(shù)

    一個是“”;另一個是“條件變量”。內(nèi)核中最常見的自旋
    發(fā)表于 01-10 22:08

    飛凌嵌入式ElfBoard-文件I/O的深入學(xué)習(xí)之文件

    進(jìn)行讀寫操作。采取強制性對性能的影響很大,每次進(jìn)行讀寫操作都必須檢查文件。 flock用于對文件加鎖或者解鎖,但是只能產(chǎn)生建議性,并且
    發(fā)表于 12-08 16:08

    霍爾元件在電子里是如何應(yīng)用的?用幾顆?

    霍爾元件在電子中主要通過感知磁場變化實現(xiàn)狀態(tài)檢測、自動控制、防撬報警等功能,其應(yīng)用數(shù)量取決于具體設(shè)計需求,通常為1-3顆,復(fù)雜系統(tǒng)可能更多。以下是對其應(yīng)用原理和具體數(shù)量的詳細(xì)分析: 霍爾元件在
    的頭像 發(fā)表于 11-25 15:01 ?435次閱讀

    五大認(rèn)證加冕!德施曼以“首創(chuàng)AI智能”重構(gòu)智能競爭格局

    。這是德施曼繼去年獲得高端智能“連續(xù)三年全國銷量第一、全球銷量第一”以及“核心科技引領(lǐng)全球”權(quán)威認(rèn)證之后,在權(quán)威機構(gòu)背書認(rèn)證中的另一個里程碑。中研世紀(jì)在《中國A
    的頭像 發(fā)表于 09-20 10:43 ?855次閱讀
    五大認(rèn)證加冕!德施曼以“首創(chuàng)AI智能<b class='flag-5'>鎖</b>”重構(gòu)智能<b class='flag-5'>鎖</b>競爭格局

    五大認(rèn)證加冕!德施曼以“首創(chuàng)AI智能”重構(gòu)智能競爭格局

    近日,智能領(lǐng)軍品牌德施曼獲得尚普咨詢及中研世紀(jì)兩大權(quán)威機構(gòu)頒發(fā)的中國“首創(chuàng)AI智能”、“AI智能領(lǐng)導(dǎo)者”、“AI智能全國銷量第一”、“AI智能鎖好評率第一”、“AI智能
    的頭像 發(fā)表于 09-20 10:41 ?1156次閱讀

    官網(wǎng)nrf24l01的例程demo會出現(xiàn)互斥報錯是為什么?

    我在用nrf24L01官網(wǎng)下載的例程包,用stm32進(jìn)行開發(fā),串口助手顯示互斥錯誤,有朋友遇到這個問題嗎
    發(fā)表于 09-10 06:05

    屏顯智能電子語音芯片方案新選擇

    在智能家居迅猛發(fā)展的當(dāng)下,電子已然從單純的物理安防設(shè)備,搖身一變成為家庭智能交互的關(guān)鍵入口。隨著消費者對生活品質(zhì)要求的不斷提高,對電子的功能期待也日益增長。高清顯示、流暢動態(tài)交互以及便捷的語音
    的頭像 發(fā)表于 07-25 17:57 ?752次閱讀
    屏顯智能電子<b class='flag-5'>鎖</b>語音芯片方案新選擇

    什么是電磁控制板?24路控板的使用步驟概述

    電磁控制板是一種專用于控制電磁工作狀態(tài)的電子裝置,它可以接收指令并對電磁進(jìn)行通斷電操作,從而實現(xiàn)對相關(guān)設(shè)備的鎖定和解鎖控制。電磁本身依靠電流產(chǎn)生磁場作用力來吸附或釋放
    的頭像 發(fā)表于 07-14 16:26 ?779次閱讀
    什么是電磁<b class='flag-5'>鎖</b>控制板?24路<b class='flag-5'>鎖</b>控板的使用步驟概述

    聯(lián)世界,智啟萬家,華普微藍(lán)牙智能解決方案

    密碼、指紋、刷卡與多模組合等主流門鎖形態(tài),支持與手機APP、小程序、智能中控網(wǎng)關(guān)等多終端互聯(lián),助力客戶快速實現(xiàn)智能門鎖產(chǎn)品的量產(chǎn)落地。功能亮點手機藍(lán)牙解鎖搭載BLE5.0及以上
    的頭像 發(fā)表于 06-26 15:46 ?809次閱讀
    <b class='flag-5'>鎖</b>聯(lián)世界,智啟萬家,華普微藍(lán)牙智能<b class='flag-5'>鎖</b>解決方案

    WT3000A,電子 AI 智慧語音方案強勢來襲!

    模組(WIFI+WT2606A語音芯片)或WT2606A單語音芯片電子 - AI 智慧語音解決方案,可滿足您多樣化產(chǎn)品需求!今天就帶大家深入了解一下這款寶藏方案。
    的頭像 發(fā)表于 05-28 15:52 ?740次閱讀
    WT3000A,電子<b class='flag-5'>鎖</b> AI 智慧語音方案強勢來襲!