日B视频 亚洲,啪啪啪网站一区二区,91色情精品久久,日日噜狠狠色综合久,超碰人妻少妇97在线,999青青视频,亚洲一区二卡,让本一区二区视频,日韩网站推荐

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

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

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

關(guān)于C++ 20協(xié)程最全面詳解

Linux愛好者 ? 來源:Tangwz ? 作者:計算機(jī)科學(xué) ? 2021-04-12 11:10 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

C++20 帶著 Coroutines 來了!

花了一兩周的時間后,我想寫寫 C++20 協(xié)程的基本用法,因為 C++ 的協(xié)程讓我感到很奇怪,寫一個協(xié)程程序十分費勁。讓我們拋去復(fù)雜的東西,來看看寫一個 C++ 協(xié)程需要哪些東西。

編譯器支持

由于 C++ 20 還沒被所有編譯器完全支持,首先需要確保你的編譯器實現(xiàn)了 Coroutines,可以通過下面的網(wǎng)站查看編譯器支持情況:https://en.cppreference.com/w/cpp/compiler_support#cpp20

值得一提,我使用的 MacOS 自帶的 Apple Clang 對 C++20 支持很弱,我選擇通過 Homebrew 安裝最新版的 GNU GCC (10 以上版本)來編譯。

我使用的 GNU GCC 10.2 版本編譯指令:

g++ -fcoroutines -std=c++20

Clang 支持不夠好,不推薦使用。Clang 可以使用如下命令編譯:

clang++ -std=c++20 -stdlib=libc++ -fcoroutines-ts

不推薦 Clang 還有一個理由:使用 Clang 需要 include 頭文件 《experimental/coroutine》 而不是 《coroutine》。此外,一些類型被命名為 std:xxx 而不是 std:xxx。

以下示例代碼只支持 GNU GCC 版本的編譯器。

C++ 協(xié)程簡介

在正式開始之前,我們先要理解 C++20 中協(xié)程使用的一些術(shù)語。

首先,什么是協(xié)程?

協(xié)程就是一個可以掛起(suspend)和恢復(fù)(resume)的函數(shù)(但無論如何不能是 main 函數(shù))。你可以暫停協(xié)程的執(zhí)行,去做其他事情,然后在適當(dāng)?shù)臅r候恢復(fù)到暫停的位置繼續(xù)執(zhí)行。協(xié)程讓我們使用同步方式寫異步代碼。

怎么掛起協(xié)程呢?C++ 提供了三個方法:co_await, co_yield 和 co_return。

順便說一句:coroutine 不是并行(parallelism),和 Go 語言的 goroutine 不一樣!

與你之前接觸到的協(xié)程完全不同,一個 C++ 協(xié)程一般長這樣:

0511f8d4-9b2f-11eb-8b86-12bb97331649.png

這奇怪的協(xié)程代碼涉及了 C++ 協(xié)程很重要的三個概念:

promise_type

Awaitable

std::coroutine_handle《》

在寫 C++20 的協(xié)程之前,我們必須需要先了解三個概念,可以用這三張圖來形容這三個概念:

Promise

C++ 協(xié)程的返回類型必須是 promise_type,promise_type 是一個 interface,你可以用它來控制協(xié)程,在協(xié)程的生命周期中注入自定義行為:

get_return_object:控制協(xié)程的返回對象

initial_suspend:在協(xié)程開始的時候掛起

final_suspend:在協(xié)程結(jié)束的時候掛起

協(xié)程的生命周期如下,用戶自定義的函數(shù) 《function-body》 被包裹在下面的偽代碼中(來源:http://eel.is/c++draft/dcl.fct.def.coroutine#5):

061ed03a-9b2f-11eb-8b86-12bb97331649.png

可以看到,initial_suspend 會在進(jìn)入?yún)f(xié)程(也就是函數(shù))之前執(zhí)行,final_suspend 會在協(xié)程返回之前執(zhí)行。

如果 final_suspend 真的掛起了協(xié)程,那么作為協(xié)程的調(diào)用者,你需要手動的調(diào)用 destroy 來釋放協(xié)程;如果 final_suspend 沒有掛起協(xié)程,那么協(xié)程將自動銷毀。先記住這句話,在后面還會提到。

除此之外,Promise 還有一些其它責(zé)任:

return_void()/return_value()/yield_value() 方法: 用來控制 co_return 和 co_yield的行為;

unhandled_exception() 處理異常

創(chuàng)建和銷毀協(xié)程的 stackframe

處理 stackframe 創(chuàng)建可能發(fā)生的異常

stackframe :函數(shù)運行時占用的內(nèi)存空間,是棧上的數(shù)據(jù)集合,它包括:

Local variables

Saved copies of registers modified by subprograms that could need restoration

Argument parameters

Return address

Awaitable

第二個概念是 Awaitable,Awaitable 負(fù)責(zé)管理協(xié)程掛起時的行為。

一個 Awaitable 對象可以成為 co_await 調(diào)用的對象。Awaitable 擁有以下方法:

await_ready():是否要掛起,如果返回 true,那么 co_await 就不會掛起函數(shù);

await_resume():co_await 的返回值,通常返回空;

await_suspend():協(xié)程掛起時的行為;

可以在 await_suspend 中實現(xiàn) await_ready 的效果,例如直接不掛起當(dāng)前的協(xié)程,但在調(diào)用 await_suspend 之前,編譯器必須將所有狀態(tài)捆綁到協(xié)程的 stackframe 中,這會更耗時。

有時候我們的協(xié)程并不需要自定義復(fù)雜的行為,C++ 提供了兩個默認(rèn)的 Awaitable:

066f0cee-9b2f-11eb-8b86-12bb97331649.png

suspend_always::await_ready() 總是返回 false,而 suspend_always::await_ready() 總是返回 true。其他的方法都是空的,沒有任何作用。

如果沒有其它多余的行為,我們可以在函數(shù)中直接調(diào)用 co_await std::suspend_always{} 來掛起一個函數(shù)。

Coroutine Handle

co_await 掛起函數(shù),并創(chuàng)建了一個可調(diào)用對象,這個對象可以用來恢復(fù)Hanns乎的執(zhí)行。這個可調(diào)用對象的類型就是 std::coroutine_handle《》,最常用的兩個方法是:

handle.resume():恢復(fù)協(xié)程的執(zhí)行;

handle.destroy():銷毀協(xié)程;

Coroutine Handle 很像指針,我們可以復(fù)制它,但析構(gòu)函數(shù)不會釋放相關(guān)狀態(tài)的內(nèi)存。為了避免內(nèi)存泄漏,一般要調(diào)用 handle.destroy() 來釋放(盡管在某些情況下,協(xié)程會在完成后自行銷毀——前文有提到)。同樣像指針一樣,一旦銷毀了一個 Coroutine Handle ,指向同一個協(xié)程的另一個 Coroutine Handle 將指向垃圾,并在調(diào)用時表現(xiàn)出未定義行為。

學(xué)習(xí)更復(fù)雜的用法之前,我們先看下示例。

示例

0685f77e-9b2f-11eb-8b86-12bb97331649.png

這個簡短的示例展示了 C++ 實現(xiàn)協(xié)程 “Hello world” 程序。我們執(zhí)行完 “Hello ” 后掛起函數(shù),又在執(zhí)行 handle.resume() 后恢復(fù)函數(shù)的運行。

非常簡單,不再過多解釋。

co_yield

C++ 協(xié)程與一個 Promise 交互之所以如此笨拙,有一個特殊原因就是為了 co_yield。

如果 promise 是當(dāng)前協(xié)程的 Promise 對象,那么執(zhí)行:

co_yield 《expression》;

相當(dāng)于執(zhí)行了:

co_await promise.yield_value(《expression》);

所以,需要在 promise_type 中添加一個 yield_value 方法。上面的例子可以改為:

069b7752-9b2f-11eb-8b86-12bb97331649.png

可以用 co_yield 實現(xiàn) Python 中的生成器,參考:https://lewissbaker.github.io/2018/09/05/understanding-the-promise-type

co_return

執(zhí)行 co_return 語句時:

co_return 《expression》;

相當(dāng)于執(zhí)行了:

co_return promise.return_value(《expression》); goto end;

下面再給出示例加上 co_return 的版本:

06dfe96e-9b2f-11eb-8b86-12bb97331649.png

復(fù)雜一些

到此, Awaitable 和 Coroutine Handle 好像還沒有發(fā)揮什么作用,我寫的示例程序都非常簡單。

如果我們想在協(xié)程掛起的時候,做更多的動作,一般將 Coroutine Handle 傳到 Awaitable 的 await_suspend() 中,用一個官網(wǎng)的例子展示一下:

073746dc-9b2f-11eb-8b86-12bb97331649.png

小結(jié)

本文簡單介紹了 C++ 協(xié)程,希望下次你寫 C++ 協(xié)程的時候,首先想到這三個東西:

我本人也不是編程語言專家,對于 C++ 協(xié)程總覺得有些繁瑣、怪異,或許是我并不清楚 C++ 在原有情況下支持協(xié)程的困難,但我依然覺得 C++ 團(tuán)隊可以做得更好。

我還需要花時間弄明白到底該如何在項目中使用這臃腫的協(xié)程。

不過,可以預(yù)見到的是,我們會在越來越多的 C++ 項目中看到協(xié)程的身影。比如 facebook folly 就已經(jīng)實現(xiàn)了一個實驗階段的協(xié)程框架
編輯:lyn

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

    關(guān)注

    22

    文章

    2131

    瀏覽量

    77419
  • 代碼
    +關(guān)注

    關(guān)注

    30

    文章

    4977

    瀏覽量

    74420
  • 編譯器
    +關(guān)注

    關(guān)注

    1

    文章

    1673

    瀏覽量

    51961

原文標(biāo)題:如何編寫 C++ 20 協(xié)程(Coroutines)

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

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

掃碼添加小助手

加入工程師交流群

    評論

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

    使用VectorCAST/C++的AI輔助測試功能

    從2026版本開始,VectorCAST/C++推出首批AI輔助測試功能,旨在幫助開發(fā)團(tuán)隊解決單元測試過程中的兩個核心難點:
    的頭像 發(fā)表于 04-27 14:37 ?304次閱讀

    手搓C++離散小波變換DWT程序

    關(guān)于小波變換,我們當(dāng)然可以選擇速度更快地方式來使用它。和python相比,C++編譯后的代碼在對同一組參數(shù)配置并且處理同一組數(shù)據(jù),在沒有優(yōu)化的情況下,處理速度可以快達(dá)10倍上,均不包括把結(jié)果寫入csv文件步驟的時間。下圖中的19.9s是指被處理的數(shù)據(jù)時長。
    的頭像 發(fā)表于 04-22 14:15 ?96次閱讀
    手搓<b class='flag-5'>C++</b>離散小波變換DWT程序

    C++ 11 14 17 20內(nèi)存管理-指針、智能指針和內(nèi)存池基礎(chǔ)與提升

    pan.baidu.com/s/1g64x9D_jp9ufk4uBpQBmvA?pwd=497f? 未來 C++ 底層核心:內(nèi)存管理實戰(zhàn),從指針到內(nèi)存池全鏈路進(jìn)階 站在2026年的技術(shù)潮頭,當(dāng)AI
    的頭像 發(fā)表于 04-20 15:51 ?550次閱讀

    C++與lua聯(lián)合編程

    核心課》中對“Lua 棧機(jī)制”的深度剖析,絕不僅是一次枯燥的源碼閱讀,而是一套關(guān)于“跨系統(tǒng)交易成本最小化”與“算力資產(chǎn)精準(zhǔn)重組”的底層方法論。徹底搞懂 Lua 棧,本質(zhì)上就是掌握了在 C++ 與 Lua
    發(fā)表于 04-19 16:27

    C++:const 的空間,常量也能占內(nèi)存?

    5g.On3.dg6rfgsg.cnJIWWQc++語言 c++語言5g.eu8.dg6rfgsg.cnJIWWQc++語言 c++語言5g.20V.dg6rfgsg.cnJIWWQc++語言
    發(fā)表于 04-16 19:19

    GS9001 GENLINX? EDH協(xié)處理器:功能與應(yīng)用詳解

    GS9001 GENLINX? EDH協(xié)處理器:功能與應(yīng)用詳解 在現(xiàn)代電子設(shè)備中,錯誤檢測和處理(EDH)功能對于確保數(shù)據(jù)傳輸?shù)臏?zhǔn)確性和可靠性至關(guān)重要。GS9001 GENLINX? EDH協(xié)處理器
    的頭像 發(fā)表于 04-15 10:05 ?379次閱讀

    C語言與C++的區(qū)別及聯(lián)系

    C語言和C++到底是什么關(guān)系? 首先C++C語言本來就是兩種不同的編程語言,但C++確實是對C
    發(fā)表于 12-24 07:23

    解析Linux的進(jìn)程、線程和協(xié)

    )輕量級:相對于進(jìn)程,線程的創(chuàng)建和切換開銷較小。 (3)同步與通信:線程之間需要通過同步機(jī)制(如互斥鎖、信號量)來保證數(shù)據(jù)的一致性。 協(xié)(Coroutine) 協(xié)是一種輕量級的
    發(fā)表于 12-22 11:00

    CC++之間的聯(lián)系

    1、語法兼容性: C++完全兼容C語言的語法,這意味著任何有效的C語言程序都可以直接在C++編譯器下編譯通過。 2、底層控制: C++
    發(fā)表于 12-11 06:51

    C語言和C++之間的區(qū)別是什么

    區(qū)別 1、面向?qū)ο缶幊?(OOP): C語言是一種面向過程的語言,它強調(diào)的是通過函數(shù)將任務(wù)分解為一系列步驟進(jìn)行執(zhí)行。 C++C語言的基礎(chǔ)上擴(kuò)展了面向?qū)ο蟮奶匦?,支持?class)、封裝、繼承
    發(fā)表于 12-11 06:23

    FreeRTOS任務(wù)和協(xié)的區(qū)別是什么

    1.堆棧 協(xié)是沒有堆棧分配的,是所有創(chuàng)建的協(xié)共同使用一個堆??臻g,這相比于任務(wù)來說,減少了RAM的使用空間。 2. 調(diào)度和優(yōu)先級 協(xié)
    發(fā)表于 12-08 08:18

    C++程序異常的處理機(jī)制

    1、什么是異常處理? 有經(jīng)驗的朋友應(yīng)該知道,在正常的CC++編程過程中難免會碰到程序不按照原本設(shè)計運行的情況。 最常見的有除法分母為零,數(shù)組越界,內(nèi)存分配失效、打開相應(yīng)文件失敗等等。 一個程序
    發(fā)表于 12-02 07:12

    C/C++代碼靜態(tài)測試工具Perforce QAC 2025.3的新特性

    ?Perforce Validate?中?QAC?項目的相對/根路徑的支持。C++?分析也得到了增強,增加了用于檢測 C++?并發(fā)問題的新檢查,并改進(jìn)了實體名稱和實
    的頭像 發(fā)表于 10-13 18:11 ?761次閱讀
    <b class='flag-5'>C</b>/<b class='flag-5'>C++</b>代碼靜態(tài)測試工具Perforce QAC 2025.3的新特性

    技能+1!如何在樹莓派上使用C++控制GPIO?

    和PiGPIO等庫,C++可用于編程控制樹莓派的GPIO引腳。它提供了更好的性能和控制能力,非常適合對速度和精度要求較高的硬件項目。在樹莓派社區(qū)中,關(guān)于“Python
    的頭像 發(fā)表于 08-06 15:33 ?4524次閱讀
    技能+1!如何在樹莓派上使用<b class='flag-5'>C++</b>控制GPIO?

    主流的 MCU 開發(fā)語言為什么是 C 而不是 C++

    在單片機(jī)的地界兒里,C語言穩(wěn)坐中軍帳,C++想分杯羹?難嘍。咱電子工程師天天跟那針尖大的內(nèi)存空間較勁,C++那些花里胡哨的玩意兒,在這兒真玩不轉(zhuǎn)。先說內(nèi)存這道坎兒。您當(dāng)stm32f4的256kRAM
    的頭像 發(fā)表于 05-21 10:33 ?1229次閱讀
    主流的 MCU 開發(fā)語言為什么是 <b class='flag-5'>C</b> 而不是 <b class='flag-5'>C++</b>?
    施秉县| 扎兰屯市| 永吉县| 茌平县| 蒙城县| 鄂温| 绥江县| 金昌市| 尚志市| 宿松县| 弋阳县| 阳泉市| 达尔| 盘锦市| 中西区| 鹰潭市| 偃师市| 河西区| 黔东| 清原| 沙湾县| 万盛区| 钟祥市| 治县。| 陇南市| 连江县| 盐边县| 瓦房店市| 琼海市| 安塞县| 永善县| 芷江| 北宁市| 萍乡市| 武穴市| 罗定市| 山西省| 新乡县| 商南县| 肥乡县| 昌邑市|