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

詳解C++20 協(xié)程從入門到網(wǎng)絡服務

 更新時間:2026年06月17日 09:02:58   作者:小強1988  
本文主要介紹了詳解C++20 協(xié)程從入門到網(wǎng)絡服務,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

一、開篇:為什么 C++20 協(xié)程值得你現(xiàn)在就學

2026 年了,C++20 協(xié)程早已不是實驗室里的玩具。從阿里云函數(shù)計算服務的生產(chǎn)改造,到 Boost.Asio 1.70+ 的全面擁抱,協(xié)程正在重新定義高性能服務器的編程范式。

傳統(tǒng)線程模型在十萬級并發(fā)面前已經(jīng)喘不過氣——每個線程獨占 1~8MB 棧空間,上下文切換需要陷入內核態(tài),一次切換耗時數(shù)千 CPU 周期。而協(xié)程,把這一切打回了用戶態(tài)。

協(xié)程不是線程的替代者,而是線程的解放者。  少量線程承載大量協(xié)程,才是現(xiàn)代高性能 C++ 程序的標準姿勢。

二、C++20 協(xié)程底層:三把鑰匙打開異步世界

C++20 協(xié)程不是語言層面的"線程替代",而是編譯器生成狀態(tài)機的語法糖。要掌握它,只需理解三個核心組件:

組件角色類比
promise_type協(xié)程的"大腦",控制初始/最終掛起、返回值、異常處理導演
coroutine_handle協(xié)程的"遙控器",手動觸發(fā) resume() 或 destroy()場記板
awaiter連接協(xié)程與異步事件的"橋梁",定義掛起/恢復邏輯場務

協(xié)程函數(shù)體內使用 co_await、co_yield 或 co_return 任一關鍵字,編譯器就會將其轉換為帶有 promise_type 的狀態(tài)機。協(xié)程幀(Coroutine Frame)存儲在堆上,規(guī)模通常僅幾十 KB——相比線程棧的 1MB,是 1/30 的內存占用。

三、手寫一個輕量協(xié)程調度器

廢話少說,直接上代碼。我們實現(xiàn)一個單線程 FIFO 調度器,支持協(xié)程的掛起與自動恢復。

#include <iostream>
#include <coroutine>
#include <queue>
#include <functional>
// ========== 1. Task 類型:協(xié)程的返回對象 ==========
struct Task {
    struct promise_type {
        Task get_return_object() {
            return Task{std::coroutine_handle<promise_type>::from_promise(*this)};
        }
        std::suspend_never initial_suspend() { return {}; }  // 立即執(zhí)行
        std::suspend_always final_suspend() noexcept { return {}; }  // 結束時掛起
        void return_void() {}
        void unhandled_exception() { std::terminate(); }
    };
    std::coroutine_handle<promise_type> handle;
    explicit Task(std::coroutine_handle<promise_type> h) : handle(h) {}
    ~Task() { if (handle) handle.destroy(); }
    Task(const Task&) = delete;
    Task(Task&& other) : handle(other.handle) { other.handle = nullptr; }
    void resume() { if (handle && !handle.done()) handle.resume(); }
    bool done() const { return handle.done(); }
};
// ========== 2. Scheduler:調度器核心 ==========
class Scheduler {
    std::queue<Task> tasks;
public:
    void schedule(Task task) { tasks.push(std::move(task)); }
    void run() {
        while (!tasks.empty()) {
            auto task = std::move(tasks.front());
            tasks.pop();
            task.resume();
            if (!task.done()) {
                tasks.push(std::move(task));  // 未結束則重新入隊
            }
        }
    }
};
// ========== 3. 模擬異步操作的 Awaiter ==========
struct AsyncSleep {
    int duration;
    bool await_ready() const noexcept { return false; }  // 總是掛起
    void await_suspend(std::coroutine_handle<> h) const noexcept {
        std::thread([h, d = duration]() {
            std::this_thread::sleep_for(std::chrono::seconds(d));
            h.resume();
        }).detach();
    }
    void await_resume() const noexcept {}
};
// ========== 4. 業(yè)務協(xié)程:同步寫法,異步執(zhí)行 ==========
Task async_task(Scheduler& sched, int id) {
    std::cout << "Task " << id << " starting...\n";
    co_await AsyncSleep{1};  // 掛起 1 秒,不阻塞調度器
    std::cout << "Task " << id << " step 1 done\n";
    co_await AsyncSleep{1};
    std::cout << "Task " << id << " step 2 done\n";
}
int main() {
    Scheduler sched;
    sched.schedule(async_task(sched, 1));
    sched.schedule(async_task(sched, 2));
    sched.schedule(async_task(sched, 3));
    sched.run();
    return 0;
}

輸出(三個任務交替執(zhí)行)

Task 1 starting...
Task 2 starting...
Task 3 starting...
Task 1 step 1 done
Task 2 step 1 done
Task 3 step 1 done
Task 1 step 2 done
Task 2 step 2 done
Task 3 step 2 done

這就是協(xié)作式調度的精髓:每個協(xié)程主動讓出 CPU,調度器輪流喚醒。沒有內核態(tài)切換,沒有鎖競爭,代碼卻像同步一樣清晰。

四、讓協(xié)程能循環(huán):FinalAwaiter 技巧

上面的調度器有個問題——協(xié)程執(zhí)行完就銷毀了,無法實現(xiàn)"任務循環(huán)"或"多階段執(zhí)行"。解決方案是在 final_suspend 中返回自定義 Awaiter,將協(xié)程重新注冊回調度器:

struct FinalAwaiter {
    bool await_ready() const noexcept { return false; }
    void await_suspend(std::coroutine_handle<> h) const noexcept {
        // h 指向 Task,重新入隊
        // scheduler_instance.schedule(Task{h});
    }
    void await_resume() noexcept {}
};
std::suspend_never final_suspend() noexcept {
    return {};  // 改為返回 FinalAwaiter 即可實現(xiàn)循環(huán)
}

這正是工業(yè)級協(xié)程框架(如 libco、cppcoro)的核心思路。

五、協(xié)程調度器 vs 線程池:性能正面剛

以下數(shù)據(jù)綜合自多個工業(yè)實測與基準測試(GCC 11.2 + Linux 5.4 內核環(huán)境):

指標傳統(tǒng)線程池協(xié)程調度器差距
單任務內存占用~1MB(線程棧)~幾十 KB(協(xié)程幀)約 30 倍
上下文切換開銷110 μs(內核態(tài))~幾十 ns(用戶態(tài))約 100 倍
10 萬并發(fā)連接內存>100 GB(不可行)~幾 GB(輕松)天壤之別
10 萬連接吞吐量~5000 req/s~6500 req/s(阿里云實測)+30%
平均響應延遲~50 ms~40 ms-20%
鎖競爭高(需互斥量/原子操作)極低(單線程事件循環(huán))質的區(qū)別

阿里云函數(shù)計算服務的改造是最有力的實證:引入?yún)f(xié)程池后,吞吐量從 5000 提升至 6500 請求/秒,延遲從 50ms 降至 40ms。改造的核心就是用協(xié)程替代了"一線程一連接"的傳統(tǒng)模型。

六、內存優(yōu)化:協(xié)程幀的碎片化治理

協(xié)程幀在堆上分配,默認由 malloc 管理。高并發(fā)下碎片化是隱形殺手:

策略碎片率分配時間
默認 malloc~20%~0.5 μs/次
內存池(預分配 1024 字節(jié)塊)~5%~0.1 μs/次

通過重載 promise_type 中的 operator new,將分配引導至內存池,可以將碎片率從 20% 壓到 5%,分配速度提升 5 倍。

七、實戰(zhàn)建議:什么時候用協(xié)程,什么時候用線程

場景推薦方案理由
CPU 密集計算(圖像處理、矩陣運算)線程池需要真正并行,協(xié)程無法利用多核
高并發(fā) I/O(Web 服務器、數(shù)據(jù)庫連接池)協(xié)程 + 少量線程掛起不阻塞,單線程可承載數(shù)萬協(xié)程
游戲服務器(邏輯 + 網(wǎng)絡混合)線程池處理邏輯 + 協(xié)程處理 I/O混合場景的最優(yōu)解
實時音視頻編碼線程池 + OpenMP必須多核并行

核心判斷標準:任務是 I/O 密集還是 CPU 密集?  I/O 密集選協(xié)程,CPU 密集選線程。協(xié)程補充而非替代線程——用 8 個線程承載數(shù)萬協(xié)程,才是高性能服務器的終極形態(tài)。

八、結語

C++20 協(xié)程的門檻確實不低,但回報同樣驚人。它不是銀彈,卻是 I/O 密集型高并發(fā)場景下最鋒利的那把刀。

從手寫一個幾十行的調度器開始,到理解 promise_type、awaiter、coroutine_handle 三位一體的協(xié)作機制,再到在生產(chǎn)環(huán)境中用協(xié)程池替換線程池——這條路,值得每一個 C++ 開發(fā)者走一遍。

2026 年了,別再用回調地獄折磨自己了。用同步的寫法,寫異步的邏輯,這才是 C++20 協(xié)程給你的真正自由。

到此這篇關于詳解C++20 協(xié)程從入門到網(wǎng)絡服務的文章就介紹到這了,更多相關C++20 協(xié)程內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • C++11 shared_ptr 與 make_shared源碼剖析詳解

    C++11 shared_ptr 與 make_shared源碼剖析詳解

    這篇文章主要介紹了C++11 shared_ptr 與 make_shared的源碼剖析,本文通過示例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-09-09
  • 一文搞懂C++中繼承的概念與使用

    一文搞懂C++中繼承的概念與使用

    我們都知道面向對象語言的三大特點是:**封裝,繼承,多態(tài)。**之前在類和對象部分,我們提到了C++中的封裝,那么今天呢,我們來學習一下C++中的繼承
    2022-07-07
  • C++類的定義與實現(xiàn)

    C++類的定義與實現(xiàn)

    這篇文章主要介紹了C++類的定義與實現(xiàn),違章圍繞C++類的定義的相關資料展開全文內容,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-01-01
  • C++淺析析構函數(shù)的特征

    C++淺析析構函數(shù)的特征

    既然在創(chuàng)建對象時有構造函數(shù)(給成員初始化),那么在銷毀對象時應該還有一個清除成員變量數(shù)據(jù)的操作咯,析構函數(shù)與構造函數(shù)功能相反,析構函數(shù)不是完成對象的銷毀,局部對象銷毀工作是由編譯器完成的。而對象在銷毀時會自動調用析構函數(shù),完成類的一些資源清理工作
    2022-07-07
  • C++處理輸入字符串并轉為數(shù)組的操作

    C++處理輸入字符串并轉為數(shù)組的操作

    這篇文章主要介紹了C++處理輸入字符串并轉為數(shù)組的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-01-01
  • C語言代碼實現(xiàn)簡易三子棋游戲

    C語言代碼實現(xiàn)簡易三子棋游戲

    這篇文章主要為大家詳細介紹了C語言代碼實現(xiàn)簡易三子棋游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-05-05
  • C++實現(xiàn)不能被繼承的類實例分析

    C++實現(xiàn)不能被繼承的類實例分析

    這篇文章主要介紹了C++實現(xiàn)不能被繼承的類實例分析,對于C++初學者而言可以通過本文實例更好的理解類的原理及運用,需要的朋友可以參考下
    2014-08-08
  • C++ 取地址符相關的默認函數(shù)

    C++ 取地址符相關的默認函數(shù)

    本文主要介紹了C++ 取地址符相關的默認函數(shù),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2026-03-03
  • QT調用vs2019生成的c++動態(tài)庫的方法實現(xiàn)

    QT調用vs2019生成的c++動態(tài)庫的方法實現(xiàn)

    本文主要介紹了QT調用vs2019生成的c++動態(tài)庫的方法實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2024-06-06
  • C/C++ break和continue區(qū)別及使用方法

    C/C++ break和continue區(qū)別及使用方法

    這篇文章主要介紹了C/C++ break和continue區(qū)別及使用方法的相關資料,需要的朋友可以參考下
    2017-07-07

最新評論

怀集县| 米脂县| 龙门县| 桐城市| 芜湖县| 视频| 乡宁县| 渝北区| 读书| 航空| 临朐县| 临湘市| 黄梅县| 景泰县| 名山县| 杭锦旗| 普陀区| 巴中市| 惠东县| 萨迦县| 苗栗县| 双城市| 馆陶县| 宜兰县| 鄂托克旗| 哈尔滨市| 托里县| 嘉兴市| 都匀市| 长顺县| 桂平市| 昂仁县| 双鸭山市| 嘉定区| 平远县| 宾川县| 年辖:市辖区| 鄂伦春自治旗| 崇阳县| 宜川县| 舟曲县|