国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

C++多線程性能優化實戰:從互斥鎖到無鎖編程完全指南

開發
如果你正在做多線程開發,或者想提升程序性能,這篇文章絕對不容錯過!

一、從一個簡單的例子開始

假設你正在開發一個計數器程序,多個線程需要同時增加這個計數器的值:

// 第一版:沒有任何保護的代碼(錯誤示例!)
class Counter {
    int count = 0;
public:
    void increment() {
        count++;  // 看起來很簡單,但在多線程下有問題!
    }
    
    int get() { return count; }
};

問題在哪里?

count++ 這一行代碼看起來是一個操作,但在CPU層面實際上是三個步驟:

// count++ 實際上被拆分成:
1. 從內存讀取 count 的值到寄存器  (LOAD)
2. 在寄存器中加1                    (ADD)
3. 把結果寫回內存                   (STORE)

如果兩個線程同時執行,就可能發生這種情況:

時間線:
┌─────────┬──────────────────────┬──────────────────────┐
│  時刻   │      線程1           │      線程2           │
├─────────┼──────────────────────┼──────────────────────┤
│   T1    │ LOAD count (得到0)   │                      │
│   T2    │                      │ LOAD count (也得到0) │
│   T3    │ ADD (計算出1)        │                      │
│   T4    │                      │ ADD (計算出1)        │
│   T5    │ STORE 1 到count      │                      │
│   T6    │                      │ STORE 1 到count      │
└─────────┴──────────────────────┴──────────────────────┘

結果: count = 1 (但期望是2!)

這就是著名的數據競爭(Data Race) 問題!

二、傳統解決方案:使用互斥鎖(Mutex)

為了解決數據競爭,最常見的方法是使用互斥鎖:

#include <mutex>

class SafeCounter {
    int count = 0;
    std::mutex mtx;  // 加一把鎖
    
public:
    void increment() {
        mtx.lock();      // 加鎖
        count++;         // 臨界區:只有一個線程能執行
        mtx.unlock();    // 解鎖
    }
    
    int get() {
        std::lock_guard<std::mutex> lock(mtx);  // RAII方式自動加鎖/解鎖
        return count;
    }
};

互斥鎖的好處:

  • 正確性保證:確保同一時刻只有一個線程修改數據
  • 簡單易懂:概念清晰,容易使用
  • 標準支持:C++11標準庫提供,跨平臺

三、互斥鎖的性能開銷

但是,鎖并非沒有代價!讓我們看看實際的性能數據:

1. 實測數據對比

根據多個benchmark研究的結果:

操作類型

執行時間

相對開銷

普通的整數加法

~1 納秒

1x (基準)

無競爭時的mutex加鎖/解鎖

~25-50 納秒

25-50x

有競爭時的mutex加鎖/解鎖

~700+ 納秒

700x+

讓我們用一個真實的benchmark來驗證:

#include <iostream>
#include <chrono>
#include <thread>
#include <mutex>
#include <vector>

// 測試1:使用mutex的計數器
class MutexCounter {
    int count = 0;
    std::mutex mtx;
public:
    void increment() {
        std::lock_guard<std::mutex> lock(mtx);
        count++;
    }
    int get() { return count; }
};

// 測試2:無保護的計數器(僅用于對比性能,實際不安全!)
class UnsafeCounter {
    int count = 0;
public:
    void increment() {
        count++;  // 不安全!僅用于測試性能基準
    }
    int get() { return count; }
};

// Benchmark函數
template<typename CounterType>
void benchmark(const std::string& name, int iterations) {
    CounterType counter;
    
    auto start = std::chrono::high_resolution_clock::now();
    
    for (int i = 0; i < iterations; i++) {
        counter.increment();
    }
    
    auto end = std::chrono::high_resolution_clock::now();
    auto duration = std::chrono::duration_cast<std::chrono::nanoseconds>(end - start);
    
    std::cout << name << ": "
              << duration.count() / iterations << " ns/op\n";
}

int main() {
    constint ITERATIONS = 1000000;
    
    benchmark<UnsafeCounter>("無保護(基準)", ITERATIONS);
    benchmark<MutexCounter>("Mutex加鎖", ITERATIONS);
    
    return0;
}

典型輸出結果:

無保護(基準): 1 ns/op
Mutex加鎖: 30ns/op

2. 關鍵洞察

即使在沒有競爭的情況下(單線程順序執行),mutex也有約幾十納秒的固定開銷!這包括:

  • 檢查鎖狀態
  • 內存屏障操作(確保可見性)
  • 函數調用開銷

四、鎖在高并發下的災難性表現

當多個線程真正競爭同一個鎖時,情況會變得更糟:

#include <thread>
#include <vector>
#include <atomic>

// 多線程競爭測試
void multithread_benchmark() {
    constint NUM_THREADS = 8;
    constint INCREMENTS_PER_THREAD = 1000000;
    
    MutexCounter counter;
    std::vector<std::thread> threads;
    
    auto start = std::chrono::high_resolution_clock::now();
    
    // 啟動多個線程,都競爭同一個鎖
    for (int i = 0; i < NUM_THREADS; i++) {
        threads.emplace_back([&counter, INCREMENTS_PER_THREAD]() {
            for (int j = 0; j < INCREMENTS_PER_THREAD; j++) {
                counter.increment();
            }
        });
    }
    
    // 等待所有線程完成
    for (auto& t : threads) {
        t.join();
    }
    
    auto end = std::chrono::high_resolution_clock::now();
    auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
    
    std::cout << "8個線程競爭鎖: " << duration.count() << " ms\n";
}

典型結果:

  • 單線程完成100萬次操作: ~30ms
  • 8線程實際使用mutex: ~650ms

慢了20多倍!

五、鎖導致的四大問題

問題1: 鎖競爭(Lock Contention)

當多個線程頻繁競爭同一個鎖時,大量時間會浪費在等待上,導致CPU利用率降低。

想象一下公共廁所的場景:

只有1個廁所門(鎖)
 有10個人排隊等待

 每個人使用廁所需要1分鐘
 但是等待+上鎖+解鎖 加起來需要5分鐘!

→ 真正干活的時間只有1/5,其余都在等待
問題2: 優先級反轉(Priority Inversion)

高優先級任務被低優先級任務間接阻塞,違反了優先級調度模型。

真實案例:1997年火星探路者號險些失敗!

火星探路者號著陸器在收集氣象數據時開始經歷系統重啟和數據丟失,問題被追溯到優先級反轉。

場景模擬:

┌────────────────────────────────────────┐
│ 高優先級任務H: 緊急氣象數據收集           │  被迫等待!
│ (需要訪問共享數據庫)                     │
└────────────────────────────────────────┘
              ? 等待鎖
┌────────────────────────────────────────┐
│ 中優先級任務M: 普通圖像處理              │  正在運行
│ (不需要數據庫)                          │
└────────────────────────────────────────┘
              ? 搶占了L的CPU
┌────────────────────────────────────────┐
│ 低優先級任務L: 后臺數據整理              │ 持有鎖,但被M搶占
│ (正持有數據庫的鎖)                      │
└────────────────────────────────────────┘

結果: H雖然優先級最高,卻被M(不需要鎖)間接阻塞!

問題3: 死鎖(Deadlock)

兩個或多個線程互相等待對方持有的鎖,導致永久阻塞:

// 經典的死鎖場景
std::mutex mutex_A;
std::mutex mutex_B;

// 線程1
void transfer_1_to_2() {
    std::lock_guard<std::mutex> lock_A(mutex_A);  // 先鎖A
    // ... 被搶占 ...
    std::lock_guard<std::mutex> lock_B(mutex_B);  // 再鎖B
    // 轉賬操作
}

// 線程2
void transfer_2_to_1() {
    std::lock_guard<std::mutex> lock_B(mutex_B);  // 先鎖B
    // ... 被搶占 ...
    std::lock_guard<std::mutex> lock_A(mutex_A);  // 再鎖A (死鎖!)
    // 轉賬操作
}

時間線:

T1: 線程1 獲得 mutex_A 
T2: 線程2 獲得 mutex_B 
T3: 線程1 嘗試獲得 mutex_B → 等待線程2釋放
T4: 線程2 嘗試獲得 mutex_A → 等待線程1釋放

→ 永久死鎖!

問題4: 活鎖(Livelock)與護航效應(Convoy Effect)

① 活鎖(Livelock)

簡單比喻:兩個人在狹窄走廊相遇,都很禮貌地想讓對方先過:

  • 甲向左讓,乙也向左讓 → 還是堵著
  • 甲向右讓,乙也向右讓 → 還是堵著
  • 不停重復,但永遠過不去!
// 活鎖場景:兩個線程都想"禮貌"地避免沖突
void polite_increment() {
    int expected = counter.load();
    while (!counter.compare_exchange_weak(expected, expected + 1)) {
        // 失敗了就"禮貌"地讓一下
        std::this_thread::yield();  
        expected = counter.load();
        // 但其他線程也在做同樣的事...無限循環!
    }
}

特點:線程都在"工作",但沒有任何實質進展。

② 護航效應(Convoy Effect)

高速公路比喻(單車道):

正常情況:

快車1  快車2 快車3  (都很快)

護航效應:

慢車A  快車1  快車2  快車3   (慢卡車拖累所有車)

鎖的護航效應:

// 線程A持有鎖,但時間片用完被操作系統暫停
{
    std::lock_guard<std::mutex> lock(shared_mutex);
    // 線程A在這里被暫停了!鎖還沒釋放
    heavy_computation(); 
} // 鎖要很久才能釋放

// 其他線程都在排隊等待
Thread B: 等待中... 
Thread C: 等待中... 
Thread D: 等待中...

問題:一個慢線程(被暫停的)拖累了所有等待的線程,就像慢卡車拖累整個車隊。

六、無鎖編程的解決思路

無鎖編程的核心思想:使用原子操作代替鎖,避免線程阻塞。

1. 使用C++11原子類型

#include <atomic>

class AtomicCounter {
    std::atomic<int> count{0};  // 原子類型
    
public:
    void increment() {
        count.fetch_add(1);  // 原子操作:不需要鎖!
    }
    
    int get() {
        return count.load();
    }
};

2. 性能對比

讓我們把兩種方案放在一起對比:

void complete_benchmark() {
    constint NUM_THREADS = 8;
    constint OPS_PER_THREAD = 1000000;
    
    // 測試1: Mutex
    {
        MutexCounter counter;
        auto start = std::chrono::high_resolution_clock::now();
        
        std::vector<std::thread> threads;
        for (int i = 0; i < NUM_THREADS; i++) {
            threads.emplace_back([&counter, OPS_PER_THREAD]() {
                for (int j = 0; j < OPS_PER_THREAD; j++)
                    counter.increment();
            });
        }
        for (auto& t : threads) t.join();
        
        auto end = std::chrono::high_resolution_clock::now();
        auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
        std::cout << "Mutex:        " << ms << " ms\n";
    }
    
    // 測試2: Atomic
    {
        AtomicCounter counter;
        auto start = std::chrono::high_resolution_clock::now();
        
        std::vector<std::thread> threads;
        for (int i = 0; i < NUM_THREADS; i++) {
            threads.emplace_back([&counter, OPS_PER_THREAD]() {
                for (int j = 0; j < OPS_PER_THREAD; j++)
                    counter.increment();
            });
        }
        for (auto& t : threads) t.join();
        
        auto end = std::chrono::high_resolution_clock::now();
        auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
        std::cout << "Atomic:       " << ms << " ms\n";
    }
}

典型結果(8核CPU):

Mutex:        608 ms
Atomic:       144 ms

4倍性能提升!

七、無鎖編程的分類

無鎖編程有三個級別,從弱到強:

1. Obstruction-Free (無阻塞)

通俗理解:"單打獨斗時能贏,打群架可能一直輸"

(1) 保證:如果只有你一個人跑(沒有其他線程干擾),一定能完成

(2) 問題:有多人競爭時,可能永遠完不成

(3) 比喻:

  • 單人游戲: 能通關
  • 多人搶游戲機: 可能誰都玩不了

2. Lock-Free (無鎖) ? 最常用

通俗理解:"保證有人能贏,但不保證每個人都能贏"

(1) 保證:整個系統一定有進展(至少一個線程能完成)

(2) 問題:個別線程可能"餓死"(一直搶不到機會)

(3) 比喻:

  • 食堂排隊打飯:總有人能打到飯(隊伍在前進)
  • 但后面的人可能一直被插隊,餓肚子

(4) 實際應用:

  • 我們講的大部分都是Lock-Free級別
  • 無鎖棧、無鎖隊列、無鎖哈希表都屬于這一類

3. Wait-Free (無等待) 最強但最難

通俗理解:"保證每個人都能贏"

(1) 保證:每個線程都能在有限步驟內完成(公平性最強!)

(2) 代價:實現極其復雜,性能不一定最好

(3) 比喻:

  • 每個人都有自己的打飯窗口: 每個人都保證能打到飯,沒有人會餓著
  • 但成本很高(需要很多窗口)

4. 三者關系圖

包含關系(集合論):

┌─────────────────────────────────┐
│ Obstruction-Free (最弱保證)    │
│  ┌──────────────────────────┐  │
│  │ Lock-Free (中等保證)     │  │
│  │  ┌───────────────────┐   │  │
│  │  │ Wait-Free (最強)  │   │  │
│  │  └───────────────────┘   │  │
│  └──────────────────────────┘  │
└─────────────────────────────────┘

難度對比:

Wait-Free >>> Lock-Free >> Obstruction-Free
(難炸天)    (有點難)     (相對簡單)

實用性對比:

  • Lock-Free ← 我們主要學這個
  • Wait-Free ← 了解即可
  • Obstruction-Free ← 理論基礎

5. 小結

(1) 活鎖:都在動,但沒進展(太客氣了)

(2) 護航效應:一個慢線程拖累所有人(單車道堵車)

(3) 無鎖分類:

  • Obstruction-Free:單打獨斗能贏
  • Lock-Free:保證有人贏 ← 重點掌握
  • Wait-Free:保證每人都贏(太難了)

記住:我們課程大部分的內容都是講Lock-Free無鎖編程,這是工業界最實用的級別!

八、無鎖編程的典型應用場景

1. 適合使用無鎖的場景

(1) 高性能計數器/統計

  • 示例:網站訪問量統計、消息隊列的消息計數
  • 原因:操作簡單,競爭激烈

(2) 生產者-消費者隊列

  • 示例:日志系統、任務調度器
  • 原因:高吞吐量需求

(3) 高頻交易系統

  • 示例:股票交易撮合引擎
  • 原因:延遲敏感,不能容忍鎖的不確定性

(4) 游戲服務器

  • 示例:玩家位置同步、技能冷卻管理
  • 原因:實時性要求高

(5) 內存分配器

  • 示例:jemalloc、tcmalloc
  • 原因:被頻繁調用,必須極致優化

2. 不適合使用無鎖的場景

(1) 操作復雜,涉及多個數據結構

  • 示例:復雜的事務系統
  • 原因:無鎖實現會極其復雜

(2) 低頻操作

  • 示例:配置文件每小時讀取一次
  • 原因:鎖的開銷可以忽略不計

(3) 已有成熟的有鎖方案且性能足夠

原因:過早優化是萬惡之源

責任編輯:趙寧寧 來源: 跟著小康學編程
相關推薦

2024-06-24 08:10:00

C++互斥鎖

2018-10-25 15:55:44

Java多線程鎖優化

2020-08-26 08:59:58

Linux線程互斥鎖

2025-09-28 04:00:00

2024-06-28 08:45:58

2025-05-06 08:20:00

互斥鎖C++編程

2024-11-05 16:29:57

2023-06-09 07:59:37

多線程編程鎖機制

2025-03-25 09:00:00

2024-03-04 00:20:00

C#線程代碼

2012-05-18 10:36:20

CC++編程

2020-06-28 11:14:36

多線程性能結構

2024-02-02 18:29:54

C++線程編程

2025-11-18 01:00:00

2009-12-08 10:07:29

2023-10-08 09:34:11

Java編程

2021-02-25 15:58:46

C++線程編程開發技術

2021-03-24 08:02:58

C語言

2021-11-26 06:43:19

Java分布式

2022-02-08 08:12:51

無鎖編程設計
點贊
收藏

51CTO技術棧公眾號

久久艳妇乳肉豪妇荡乳av| 欧美精品卡一卡二| 91精品久久久久久久| gay视频丨vk| 亚洲美女久久精品| 欧美日韩电影一区二区| 成人毛片高清视频观看| 日本久久伊人| 亚洲影视资源网| 亚洲在线免费视频| bt电影在线| 哺乳一区二区三区中文视频| 欧美爱爱视频免费看| 亚洲va久久久噜噜噜久久天堂| 99精产国品一二三产品香蕉| 大伊香蕉精品在线品播放| 亚洲一区二区影院| 成人免费黄色网| 色开心亚洲综合| 日韩av字幕| 欧美午夜激情在线| 国产乱码精品一区二区三区卡| 日韩一区二区三区在线免费观看 | 国产高清不卡一区| 亚洲第一二三四五区| 一级特黄录像免费播放全99| 麻豆理论在线观看| 久久精品夜夜夜夜久久| 久久综合九色综合网站| 午夜综合激情| 亚洲精品中文字幕无码蜜桃| 精品一区二区三区欧美| 91精品国产一区二区三区| 成人免费看黄网址| 国产色91在线| 91好吊色国产欧美日韩在线| 亚洲小说欧美另类婷婷| 日韩欧美在线观看强乱免费| 日韩欧美一级精品久久| 波多野结衣亚洲| xxav国产精品美女主播| 污污影院在线观看| 亚洲电影免费观看高清完整版在线| 国产精品va视频| 亚洲一二三区视频在线观看| 明星裸体视频一区二区| 国产一区高清| 欧美日韩一区二区在线观看视频| 综合一区中文字幕| 欧美日韩伊人| 美女黄色丝袜一区| a黄色片在线观看| 九九久久久久久久久激情| 欧美尤物美女在线| 九七电影院97理论片久久tvb| 国产欧美在线看| 日本免费新一区视频| 日本福利视频一区| 欧美国产禁国产网站cc| 在线看黄网站| 亚洲精品久久久久久久久| 欧美伊人亚洲伊人色综合动图| 91影院在线观看| 欧美一级爱爱视频| 亚洲精品免费播放| 国产精品vvv| 国产精品视频999| 国产精品久久久久婷婷| 中午字幕在线观看| 99在线观看| 久久色在线播放| 天天色综合社区| 亚洲精品小说| 日本h片在线看| 国产福利一区二区三区在线观看| 日本高清久久| 亚洲成人免费网站| 国模私拍国内精品国内av| 色综合久久88| 波多野结衣在线观看一区二区| 国产精品久久一| 亚洲精品麻豆| 在线观看av的网址| 国产精品久线在线观看| 小明精品国产一区二区三区| 欧美日本一道本在线视频| 在线男人天堂| 日本aⅴ大伊香蕉精品视频| 欧美 日韩 国产 一区| 亚洲欧洲精品一区二区| 久久精品人人做人人综合| 蜜桃视频在线免费| 亚洲人成电影网站| 热久久天天拍国产| 日韩人妻精品一区二区三区| 亚洲欧美日韩国产成人精品影院| 久热国产在线| 欧美精品国产精品日韩精品| 亚洲欧洲日本mm| 中文字幕日本最新乱码视频| 性做久久久久久免费观看| 91高清在线观看视频| 欧美大片在线免费观看| 亚洲激情女人| 麻豆三级在线观看| 91精品视频网| av综合网页| 日韩亚洲不卡在线| 18成人在线视频| 国产美女精品写真福利视频| 日韩av手机在线| 国产精品一区二区三区网站| 深夜视频在线免费| 久久天天躁狠狠躁夜夜躁| 国内视频精品| 狠狠躁狠狠躁视频专区| 亚洲成av人片在线观看香蕉| 欧美少妇xxxx| 成年人视频观看| 日韩欧美一二三四区| 精品高清在线| 日韩中文字幕二区| 日韩免费高清av| 欧美激情777| 久久黄色免费看| 日韩风俗一区 二区| 国产精品欧美日韩一区| jizzjizz国产精品喷水| 91精品国产一区二区| 成人同人动漫免费观看| 少妇性饥渴无码a区免费| 欧美大胆一级视频| 欧美午夜一区| 在线播放evaelfie极品| 欧美激情视频播放| 成人中文字幕合集| 最新超碰在线| 国产欧美韩日| 欧美性xxxx18| 欧美日韩一二三四| 日本超碰在线观看| 在线丨暗呦小u女国产精品| 激情久久综合| 理论在线观看| 成人做爰www免费看视频网站| 国产欧美日韩激情| 激情欧美一区二区三区黑长吊| 日韩精品资源| 日韩美女视频在线| 一区二区日韩免费看| 免费国产在线视频| 91精品视频大全| 精品久久久久久| 99精品一区| 天堂网www中文在线| 国产中文字幕日韩| 一区二区三区四区国产精品| 精品综合久久88少妇激情| 少妇黄色一级片| 久久久亚洲国产| 亚洲国产精品ⅴa在线观看| 视频一区日韩| 成人免费淫片在线费观看| 久久久亚洲国产| 成人免费在线观看入口| 午夜精品影视国产一区在线麻豆| 亚洲免费看av| 日本一区二区不卡| 亚洲成人一二三| 欧美日韩伊人| 久久不射影院| 大陆极品少妇内射aaaaaa| 中文字幕欧美日韩va免费视频| 国产一区二区三区精品欧美日韩一区二区三区 | 色综合久久久久久久久| 日韩精品一区二区三区免费观看| 成人在线看片网站| 国产精品爱啪在线线免费观看| 国产精品进线69影院| 视频福利一区| 国产高清免费av在线| 欧美日韩国产精品一卡| 亚洲激情第一页| www.欧美.com| 免费黄色成人| yourporn在线观看视频| 亚洲国产精品久久久久久女王| 日日噜噜噜夜夜爽亚洲精品| 国产精品丝袜一区| 天天射综合网视频| 欧美人与动牲性行为| 精品人妻少妇一区二区| 欧美激情一区二区三区高清视频 | 欧洲黄色一级视频| 午夜精品久久久久久久久久久久| 亚洲欧美日韩电影| 99热在线精品观看| 欧美97人人模人人爽人人喊视频| 激情五月俺来也| 精品一区在线播放|