C++鎖機(jī)制與信號(hào)機(jī)制對(duì)比分析
前言
在C++中,多線程編程的線程同步和通信主要依賴于鎖機(jī)制和信號(hào)機(jī)制。
一、鎖機(jī)制
鎖用于控制對(duì)共享資源的訪問(wèn),防止多個(gè)線程同時(shí)修改數(shù)據(jù)導(dǎo)致競(jìng)態(tài)條件。
- 互斥鎖(Mutex)
作用:確保同一時(shí)間只有一個(gè)線程能訪問(wèn)共享資源。
類(lèi)型:
○ std::mutex:基本互斥鎖。
○ std::recursive_mutex:允許同一線程多次加鎖(解決遞歸調(diào)用中的鎖問(wèn)題)。
○ std::shared_mutex(C++17):讀寫(xiě)鎖,允許多個(gè)讀線程或單個(gè)寫(xiě)線程訪問(wèn)。
基本用法
#include <mutex>
std::mutex mtx;
void thread_func() {
mtx.lock();
// 訪問(wèn)共享資源
mtx.unlock();
}RAII包裝器(推薦使用,避免手動(dòng)解鎖):
std::lock_guard:自動(dòng)在作用域內(nèi)加鎖和解鎖。
{
std::lock_guard<std::mutex> lock(mtx);
// 自動(dòng)加鎖,離開(kāi)作用域自動(dòng)解鎖
}std::unique_lock:更靈活,支持延遲加鎖和手動(dòng)控制。
std::unique_lock<std::mutex> lock(mtx, std::defer_lock); lock.lock(); // 手動(dòng)加鎖 // ... lock.unlock(); // 可提前解鎖
- 讀寫(xiě)鎖(Shared Mutex)
適用場(chǎng)景:讀多寫(xiě)少的情況,提高并發(fā)性能。
用法:
#include <shared_mutex>
std::shared_mutex rw_mtx;
// 讀操作(共享鎖)
{
std::shared_lock<std::shared_mutex> lock(rw_mtx);
// 多個(gè)讀線程可同時(shí)訪問(wèn)
}
// 寫(xiě)操作(獨(dú)占鎖)
{
std::unique_lock<std::shared_mutex> lock(rw_mtx);
// 僅一個(gè)寫(xiě)線程可訪問(wèn)
}- 死鎖預(yù)防
原則:
a. 按固定順序加鎖。
b. 使用std::lock同時(shí)加多個(gè)鎖(避免死鎖)。
std::lock(mtx1, mtx2); // 原子性鎖定多個(gè)互斥量 std::lock_guard<std::mutex> lock1(mtx1, std::adopt_lock); std::lock_guard<std::mutex> lock2(mtx2, std::adopt_lock);
二、信號(hào)機(jī)制(條件變量)
- 核心操作
- 等待(Wait):線程在條件不滿足時(shí)掛起。 通知(Notify):條件滿足時(shí)喚醒等待的線程。
notify_one():?jiǎn)拘岩粋€(gè)等待線程。
notify_all():?jiǎn)拘阉械却€程。
基本用法等待條件(需配合互斥鎖和謂詞檢查):
std::mutex mtx;
std::condition_variable cv;
bool data_ready = false;
// 等待線程
{
std::unique_lock<std::mutex> lock(mtx);
cv.wait(lock, [] { return data_ready; }); // 防止虛假喚醒
// 條件滿足后執(zhí)行操作
}
// 通知線程
{
std::lock_guard<std::mutex> lock(mtx);
data_ready = true;
cv.notify_one(); // 或 notify_all()
}- 避免虛假喚醒
使用帶有謂詞檢查的wait:
cv.wait(lock, predicate); // 等價(jià)于 while (!predicate) cv.wait(lock);
三、信號(hào)量(Semaphore)
C++20 引入了std::counting_semaphore,用于控制同時(shí)訪問(wèn)資源的線程數(shù)量。
- 基本用法
#include <semaphore> std::counting_semaphore<10> sem(3); // 最大計(jì)數(shù)10,初始3 sem.acquire(); // 計(jì)數(shù)減1(如果計(jì)數(shù)為0則阻塞) // 訪問(wèn)資源 sem.release(); // 計(jì)數(shù)加1
- 適用場(chǎng)景
● 限制并發(fā)線程數(shù)(如連接池)。
● 生產(chǎn)者-消費(fèi)者模型中的緩沖區(qū)控制。
四、鎖與信號(hào)機(jī)制的對(duì)比

到此這篇關(guān)于C++鎖機(jī)制與信號(hào)機(jī)制的文章就介紹到這了,更多相關(guān)C++鎖機(jī)制與信號(hào)機(jī)制內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++避免棧內(nèi)存溢出的幾種實(shí)現(xiàn)方法
在C++編程中,一個(gè)線程的棧內(nèi)存通常是有限的,本文就來(lái)詳細(xì)介紹幾種避免棧溢出的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2025-09-09
使用C語(yǔ)言順序表數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn)棧的代碼示例
這篇文章主要給大家介紹了如何使用C語(yǔ)言順序表數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn)棧,文章通過(guò)代碼示例介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作有一定的參考價(jià)值,需要的朋友可以參考下2023-09-09
介紹C語(yǔ)言中tolower函數(shù)的實(shí)例
這篇文章主要介紹了介紹C語(yǔ)言中tolower函數(shù)的實(shí)例,本文列出了該函數(shù)的頭文件,功能說(shuō)明等,以及如何使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07
C語(yǔ)言實(shí)現(xiàn)學(xué)籍管理系統(tǒng)課程設(shè)計(jì)
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)學(xué)籍管理系統(tǒng)課程設(shè)計(jì),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-07-07
利用C++實(shí)現(xiàn)最長(zhǎng)公共子序列與最長(zhǎng)公共子串
這篇文章主要給大家介紹了如何利用C++實(shí)現(xiàn)最長(zhǎng)公共子序列與最長(zhǎng)公共子串,文章一開(kāi)始就給大家簡(jiǎn)單的介紹了什么是子序列,子串應(yīng)該比較好理解就不用多介紹了,人后通過(guò)算法及示例代碼詳細(xì)介紹了C++實(shí)現(xiàn)的方法,有需要的朋友們可以參考借鑒,下面來(lái)一起看看吧。2016-12-12

