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

C++中無(wú)鎖隊(duì)列與有鎖隊(duì)列的實(shí)現(xiàn)

 更新時(shí)間:2026年06月04日 09:59:43   作者:晴雨日記  
本文詳細(xì)介紹了C++中無(wú)鎖隊(duì)列與有鎖隊(duì)列的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

一、有鎖隊(duì)列實(shí)現(xiàn)詳解

#include <queue>
#include <mutex>
#include <condition_variable>

template <typename T>
class LockedQueue {
private:
    std::queue<T> queue_;
    mutable std::mutex mutex_;
    std::condition_variable cond_;

public:
    // 插入元素(線(xiàn)程安全)
    void push(T value) {
        {
            std::lock_guard<std::mutex> lock(mutex_);
            queue_.push(std::move(value));
        }  // 自動(dòng)解鎖作用域
        cond_.notify_one();  // 通知等待線(xiàn)程
    }

    // 非阻塞彈出(立即返回)
    bool try_pop(T& value) {
        std::lock_guard<std::mutex> lock(mutex_);
        if (queue_.empty()) return false;
        value = std::move(queue_.front());
        queue_.pop();
        return true;
    }

    // 阻塞式彈出(等待元素)
    void wait_and_pop(T& value) {
        std::unique_lock<std::mutex> lock(mutex_);
        // 條件等待:防止虛假喚醒
        cond_.wait(lock, [this] { return !queue_.empty(); });
        value = std::move(queue_.front());
        queue_.pop();
    }

    // 可選:隊(duì)列大?。ǚ蔷_值)
    size_t size() const {
        std::lock_guard<std::mutex> lock(mutex_);
        return queue_.size();
    }
};

核心機(jī)制分析

  1. 鎖保護(hù)

    • 使用 std::mutex 保護(hù)所有隊(duì)列操作
    • std::lock_guard 實(shí)現(xiàn) RAII 式自動(dòng)鎖管理
    • 鎖粒度控制:push 操作中鎖僅保護(hù)入隊(duì)操作
  2. 條件變量

    • 解決消費(fèi)者空輪詢(xún)問(wèn)題
    • wait() 包含謂詞檢查 [this] { return !queue_.empty(); } 防止虛假喚醒
    • notify_one() 精確喚醒一個(gè)等待線(xiàn)程
  3. 性能特點(diǎn)

    • 低競(jìng)爭(zhēng)時(shí):鎖開(kāi)銷(xiāo)約 20-50ns
    • 高競(jìng)爭(zhēng)時(shí):線(xiàn)程切換開(kāi)銷(xiāo)急劇上升(微秒級(jí))
    • 典型瓶頸:鎖爭(zhēng)用導(dǎo)致 CPU 利用率下降

二、無(wú)鎖隊(duì)列實(shí)現(xiàn)詳解(SPSC )

#include <atomic>
#include <memory>
#include <vector>

template <typename T>
class LockFreeSPSCQueue {
private:
    struct Node {
        std::atomic<Node*> next;
        T data;
        Node() : next(nullptr) {}  // Dummy node
        Node(T val) : data(std::move(val)), next(nullptr) {}
    };

    // 緩存行對(duì)齊(64字節(jié))防止偽共享
    alignas(64) std::atomic<Node*> head_;
    alignas(64) std::atomic<Node*> tail_;

    // 預(yù)分配節(jié)點(diǎn)池(減少內(nèi)存分配開(kāi)銷(xiāo))
    std::vector<std::unique_ptr<Node>> node_pool_;

    Node* alloc_node(T value = T{}) {
        node_pool_.push_back(std::make_unique<Node>(std::move(value)));
        return node_pool_.back().get();
    }

public:
    LockFreeSPSCQueue() {
        Node* dummy = alloc_node();  // 創(chuàng)建虛擬節(jié)點(diǎn)
        head_.store(dummy, std::memory_order_relaxed);
        tail_.store(dummy, std::memory_order_relaxed);
    }

    ~LockFreeSPSCQueue() {
        // 自動(dòng)清理通過(guò) unique_ptr 管理
    }

    // 生產(chǎn)者操作
    void push(T value) {
        Node* new_node = alloc_node(std::move(value));
        Node* old_tail = tail_.exchange(new_node, std::memory_order_acq_rel);
        
        // 關(guān)鍵:先設(shè)置 tail 再連接 next
        old_tail->next.store(new_node, std::memory_order_release);
    }

    // 消費(fèi)者操作
    bool pop(T& value) {
        Node* old_head = head_.load(std::memory_order_relaxed);
        Node* next_ptr = old_head->next.load(std::memory_order_acquire);

        if (!next_ptr) return false;  // 空隊(duì)列
        
        // 移動(dòng)數(shù)據(jù)并更新頭節(jié)點(diǎn)
        value = std::move(next_ptr->data);
        head_.store(next_ptr, std::memory_order_release);
        
        // 回收舊頭節(jié)點(diǎn)(實(shí)際由 node_pool_ 統(tǒng)一管理)
        old_head->next.store(nullptr, std::memory_order_relaxed);
        return true;
    }
};

關(guān)鍵技術(shù)創(chuàng)新

  1. 內(nèi)存序優(yōu)化

    • push()exchange 使用 acq_rel 確保寫(xiě)可見(jiàn)性
    • pop()load 使用 acquire 保證讀取順序
    • 生產(chǎn)者-消費(fèi)者分離:通過(guò) release-acquire 對(duì)同步
  2. 偽共享預(yù)防

    alignas(64) std::atomic<Node*> head_;  // 單獨(dú)緩存行
    alignas(64) std::atomic<Node*> tail_;  // 單獨(dú)緩存行
    
    • 避免 head/tail 競(jìng)爭(zhēng)同一緩存行(提升 2-3 倍性能)
  3. 內(nèi)存管理優(yōu)化

    • 預(yù)分配節(jié)點(diǎn)池:消除動(dòng)態(tài)分配開(kāi)銷(xiāo)
    • 虛擬節(jié)點(diǎn)模式:始終存在至少一個(gè)節(jié)點(diǎn)
    • 批量釋放:通過(guò) vector<unique_ptr> 自動(dòng)回收
  4. 無(wú)鎖保證

    • 生產(chǎn)者操作:?jiǎn)未?exchange 原子操作
    • 消費(fèi)者操作:?jiǎn)未?load + store
    • 無(wú)忙等待:消費(fèi)者直接返回狀態(tài)

三、性能對(duì)比基準(zhǔn)測(cè)試(參考數(shù)據(jù))

測(cè)試環(huán)境:Intel Xeon Gold 6248, 20 線(xiàn)程, GCC 11.2
測(cè)試場(chǎng)景:10M 次操作(50% push / 50% pop)

| 隊(duì)列類(lèi)型        | 線(xiàn)程數(shù) | 耗時(shí)(ms) | 吞吐量(ops/ms) |
|----------------|--------|----------|---------------|
| 有鎖隊(duì)列        | 1P1C   | 285      | 35,087        |
| 有鎖隊(duì)列        | 2P2C   | 1,420    | 7,042         |
| 有鎖隊(duì)列        | 4P4C   | 3,850    | 2,597         |
|---------------|--------|----------|---------------|
| 無(wú)鎖隊(duì)列(SPSC) | 1P1C   | 78       | 128,205       |
| boost::lockfree| 4P4C   | 210      | 47,619        |

性能結(jié)論

  1. SPSC 場(chǎng)景:無(wú)鎖隊(duì)列比有鎖快 3-5 倍
  2. MPMC 場(chǎng)景:有鎖隊(duì)列性能斷崖式下降
  3. 高競(jìng)爭(zhēng)時(shí):專(zhuān)業(yè)無(wú)鎖庫(kù)(如 Boost)仍保持線(xiàn)性擴(kuò)展

四、關(guān)鍵問(wèn)題深度解析

問(wèn)題 1:ABA 問(wèn)題如何解決?
在 SPSC 中不會(huì)發(fā)生 ABA(單消費(fèi)者),MPMC 解決方案:

// 使用帶標(biāo)記指針的原子操作
struct TaggedPtr {
    Node* ptr;
    uintptr_t tag;  // 操作計(jì)數(shù)器
};

std::atomic<TaggedPtr> head_;

bool pop(T& value) {
    TaggedPtr old_head = head_.load();
    while (true) {
        Node* next = old_head.ptr->next.load();
        if (!next) return false;
        TaggedPtr new_head{next, old_head.tag + 1};
        if (head_.compare_exchange_weak(old_head, new_head)) {
            value = next->data;
            return true;
        }
    }
}

問(wèn)題 2:內(nèi)存回收挑戰(zhàn)
無(wú)鎖隊(duì)列內(nèi)存安全方案:

  1. 危險(xiǎn)指針(Hazard Pointers):線(xiàn)程注冊(cè)正在訪(fǎng)問(wèn)的指針
  2. 引用計(jì)數(shù):shared_ptr 的原子特化版本
  3. 紀(jì)元回收(Epoch-Based):延遲回收(本實(shí)現(xiàn)采用預(yù)分配+批量回收)

問(wèn)題 3:何時(shí)選擇無(wú)鎖隊(duì)列?
適用場(chǎng)景:

  • 實(shí)時(shí)系統(tǒng)(避免優(yōu)先級(jí)反轉(zhuǎn))
  • 高頻交易(納秒級(jí)延遲要求)
  • 線(xiàn)程數(shù) > CPU 核心數(shù)的高競(jìng)爭(zhēng)場(chǎng)景

不適用場(chǎng)景:

  • 低競(jìng)爭(zhēng)環(huán)境(鎖更簡(jiǎn)單)
  • 內(nèi)存受限系統(tǒng)(無(wú)鎖內(nèi)存開(kāi)銷(xiāo)大)
  • 算法復(fù)雜度敏感場(chǎng)景

五、生產(chǎn)環(huán)境最佳實(shí)踐

  1. 有鎖隊(duì)列優(yōu)化技巧

    // 使用細(xì)粒度鎖(分離頭尾鎖)
    mutable std::mutex head_mutex_;
    mutable std::mutex tail_mutex_;
    
  2. 無(wú)鎖隊(duì)列使用建議

    // 使用成熟庫(kù)(避免自行實(shí)現(xiàn))
    #include <boost/lockfree/queue.hpp>
    boost::lockfree::queue<int> queue(128);
    
  3. 混合方案

    • 多級(jí)隊(duì)列:無(wú)鎖緩沖區(qū) + 批處理鎖
    • 工作竊?。好總€(gè)線(xiàn)程本地隊(duì)列 + 無(wú)鎖全局隊(duì)列
  4. 性能調(diào)優(yōu)工具

    perf stat -e L1-dcache-load-misses,cache-misses ./a.out
    valgrind --tool=helgrind ./a.out  # 檢測(cè)競(jìng)爭(zhēng)
    

終極建議:

  1. 首選有鎖隊(duì)列(除非性能驗(yàn)證需要)
  2. SPSC 場(chǎng)景用無(wú)鎖隊(duì)列
  3. MPMC 場(chǎng)景用 moodycamel::ConcurrentQueue
  4. 實(shí)時(shí)系統(tǒng)用 boost::lockfree::spsc_queue

到此這篇關(guān)于C++中無(wú)鎖隊(duì)列與有鎖隊(duì)列的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)C++ 無(wú)鎖隊(duì)列與有鎖隊(duì)列內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C語(yǔ)言由淺入深講解文件的操作下篇

    C語(yǔ)言由淺入深講解文件的操作下篇

    C語(yǔ)言具有操作文件的能力,比如打開(kāi)文件、讀取和追加數(shù)據(jù)、插入和刪除數(shù)據(jù)、關(guān)閉文件、刪除文件等。與其他編程語(yǔ)言相比,C語(yǔ)言文件操作的接口相當(dāng)簡(jiǎn)單和易學(xué)
    2022-04-04
  • 深入理解c++指針的指針和指針的引用

    深入理解c++指針的指針和指針的引用

    下面小編就為大家?guī)?lái)一篇深入理解c++指針的指針和指針的引用。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考,一起跟隨小編過(guò)來(lái)看看吧
    2016-06-06
  • 深入理解c++20 concepts

    深入理解c++20 concepts

    本文主要介紹了深入理解c++20 concepts,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • 深入探討C語(yǔ)言中局部變量與全局變量在內(nèi)存中的存放位置

    深入探討C語(yǔ)言中局部變量與全局變量在內(nèi)存中的存放位置

    本篇文章是對(duì)在C語(yǔ)言中局部變量與全局變量在內(nèi)存中的存放位置進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • C語(yǔ)言實(shí)現(xiàn)通用數(shù)據(jù)結(jié)構(gòu)之通用集合(HashSet)

    C語(yǔ)言實(shí)現(xiàn)通用數(shù)據(jù)結(jié)構(gòu)之通用集合(HashSet)

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)通用數(shù)據(jù)結(jié)構(gòu)之通用集合,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • 帶你搞懂C++ LeeCode 二叉樹(shù)的中序遍歷

    帶你搞懂C++ LeeCode 二叉樹(shù)的中序遍歷

    中序遍歷(LDR)是二叉樹(shù)遍歷的一種,也叫做中根遍歷、中序周游。在二叉樹(shù)中,中序遍歷首先遍歷左子樹(shù),然后訪(fǎng)問(wèn)根結(jié)點(diǎn),最后遍歷右子樹(shù)
    2021-07-07
  • C++實(shí)現(xiàn)簡(jiǎn)單通訊錄管理系統(tǒng)

    C++實(shí)現(xiàn)簡(jiǎn)單通訊錄管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)簡(jiǎn)單通訊錄管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • C++異常處理方式實(shí)例詳解(超級(jí)詳細(xì)!)

    C++異常處理方式實(shí)例詳解(超級(jí)詳細(xì)!)

    程序有時(shí)會(huì)遇到運(yùn)行階段錯(cuò)誤,導(dǎo)致程序無(wú)法正常執(zhí)行下去,c++異常為處理這種情況提供了一種功能強(qiáng)大的而靈活的工具,下面這篇文章主要給大家介紹了關(guān)于C++異常處理方式的相關(guān)資料,需要的朋友可以參考下
    2023-04-04
  • ???????C語(yǔ)言實(shí)現(xiàn)單鏈表基本操作方法

    ???????C語(yǔ)言實(shí)現(xiàn)單鏈表基本操作方法

    這篇文章主要介紹了???????C語(yǔ)言實(shí)現(xiàn)單鏈表基本操作方法,文章圍繞主題展開(kāi)詳細(xì)介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2022-05-05
  • C語(yǔ)言如何實(shí)現(xiàn)循環(huán)輸入

    C語(yǔ)言如何實(shí)現(xiàn)循環(huán)輸入

    這篇文章主要介紹了C語(yǔ)言如何實(shí)現(xiàn)循環(huán)輸入問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-02-02

最新評(píng)論

浮山县| 通山县| 常山县| 高尔夫| 榆社县| 冀州市| 北票市| 赤峰市| 临西县| 土默特左旗| 台前县| 黄石市| 商水县| 南康市| 怀集县| 沈丘县| 克山县| 凤台县| 民丰县| 保靖县| 松江区| 承德市| 瑞丽市| 马公市| 凭祥市| 永德县| 商水县| 苏尼特右旗| 葫芦岛市| 双江| 马关县| 大石桥市| 庆阳市| 康马县| 连云港市| 宁城县| 平顶山市| 元朗区| 清新县| 庆城县| 安丘市|