日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當(dāng)前位置:首頁 > 單片機(jī) > C語言與CPP編程
[導(dǎo)讀]C20帶著Coroutines來了!花了一兩周的時(shí)間后,我想寫寫C20協(xié)程的基本用法,因?yàn)镃的協(xié)程讓我感到很奇怪,寫一個(gè)協(xié)程程序十分費(fèi)勁。讓我們拋去復(fù)雜的東西,來看看寫一個(gè)C協(xié)程需要哪些東西。編譯器支持由于C20還沒被所有編譯器完全支持,首先需要確保你的編譯器實(shí)現(xiàn)了Corouti...

C 20 帶著 Coroutines 來了!

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

編譯器支持

由于 C 20 還沒被所有編譯器完全支持,首先需要確保你的編譯器實(shí)現(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 還有一個(gè)理由:使用 Clang 需要 include 頭文件??而不是?。此外,一些類型被命名為?std::experimental:xxx?而不是?std:xxx。

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

C 協(xié)程簡介

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

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

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

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

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

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

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

  • promise_type

  • Awaitable

  • std::coroutine_handle<>

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

圖來源:?https://www.youtube.com/watch?v=vzC2iRfO_H8

Promise

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

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

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

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

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

可以看到,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ù)運(yùn)行時(shí)占用的內(nèi)存空間,是棧上的數(shù)據(jù)集合,它包括:

  • Local variables

  • Saved copies of registers modified by subprograms that could need restoration

  • Argument parameters

  • Return address

Awaitable

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

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

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

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

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

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

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

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

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

Coroutine Handle

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

  • 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é)程會在完成后自行銷毀——前文有提到)。同樣像指針一樣,一旦銷毀了一個(gè)?Coroutine Handle?,指向同一個(gè)協(xié)程的另一個(gè)?Coroutine Handle?將指向垃圾,并在調(diào)用時(shí)表現(xiàn)出未定義行為。

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

示例

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

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

co_yield

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

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

co_yield <expression>;
相當(dāng)于執(zhí)行了:

co_await promise.yield_value(<expression>);
所以,需要在 promise_type 中添加一個(gè)?yield_value?方法。上面的例子可以改為:

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

co_return

執(zhí)行?co_return?語句時(shí):

co_return <expression>;
相當(dāng)于執(zhí)行了:

co_return promise.return_value(<expression>); goto end;
下面再給出示例加上?co_return?的版本:

復(fù)雜一些

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

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

小結(jié)

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

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

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

不過,可以預(yù)見到的是,我們會在越來越多的 C 項(xiàng)目中看到協(xié)程的身影。比如 facebook folly 就已經(jīng)實(shí)現(xiàn)了一個(gè)實(shí)驗(yàn)階段的協(xié)程框架: https://github.com/facebook/folly/tree/master/folly/experimental/coro

也許等我再研究一段時(shí)間,會寫一篇到底該如何使用 C 協(xié)程。

Reference

  • C Coroutine definitions:?http://eel.is/c draft/dcl.fct.def.coroutine#5

  • C draft expr.await:?http://eel.is/c draft/expr.await

  • C Coroutines: Understanding the promise type:?https://lewissbaker.github.io/2018/09/05/understanding-the-promise-type

  • 官網(wǎng)的例子:https://en.cppreference.com/w/cpp/language/coroutines

  • My tutorial and take on C 20 coroutines:https://www.scs.stanford.edu/~dm/blog/c -coroutines.html#coroutine-handles

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

LED驅(qū)動電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: 驅(qū)動電源

在工業(yè)自動化蓬勃發(fā)展的當(dāng)下,工業(yè)電機(jī)作為核心動力設(shè)備,其驅(qū)動電源的性能直接關(guān)系到整個(gè)系統(tǒng)的穩(wěn)定性和可靠性。其中,反電動勢抑制與過流保護(hù)是驅(qū)動電源設(shè)計(jì)中至關(guān)重要的兩個(gè)環(huán)節(jié),集成化方案的設(shè)計(jì)成為提升電機(jī)驅(qū)動性能的關(guān)鍵。

關(guān)鍵字: 工業(yè)電機(jī) 驅(qū)動電源

LED 驅(qū)動電源作為 LED 照明系統(tǒng)的 “心臟”,其穩(wěn)定性直接決定了整個(gè)照明設(shè)備的使用壽命。然而,在實(shí)際應(yīng)用中,LED 驅(qū)動電源易損壞的問題卻十分常見,不僅增加了維護(hù)成本,還影響了用戶體驗(yàn)。要解決這一問題,需從設(shè)計(jì)、生...

關(guān)鍵字: 驅(qū)動電源 照明系統(tǒng) 散熱

根據(jù)LED驅(qū)動電源的公式,電感內(nèi)電流波動大小和電感值成反比,輸出紋波和輸出電容值成反比。所以加大電感值和輸出電容值可以減小紋波。

關(guān)鍵字: LED 設(shè)計(jì) 驅(qū)動電源

電動汽車(EV)作為新能源汽車的重要代表,正逐漸成為全球汽車產(chǎn)業(yè)的重要發(fā)展方向。電動汽車的核心技術(shù)之一是電機(jī)驅(qū)動控制系統(tǒng),而絕緣柵雙極型晶體管(IGBT)作為電機(jī)驅(qū)動系統(tǒng)中的關(guān)鍵元件,其性能直接影響到電動汽車的動力性能和...

關(guān)鍵字: 電動汽車 新能源 驅(qū)動電源

在現(xiàn)代城市建設(shè)中,街道及停車場照明作為基礎(chǔ)設(shè)施的重要組成部分,其質(zhì)量和效率直接關(guān)系到城市的公共安全、居民生活質(zhì)量和能源利用效率。隨著科技的進(jìn)步,高亮度白光發(fā)光二極管(LED)因其獨(dú)特的優(yōu)勢逐漸取代傳統(tǒng)光源,成為大功率區(qū)域...

關(guān)鍵字: 發(fā)光二極管 驅(qū)動電源 LED

LED通用照明設(shè)計(jì)工程師會遇到許多挑戰(zhàn),如功率密度、功率因數(shù)校正(PFC)、空間受限和可靠性等。

關(guān)鍵字: LED 驅(qū)動電源 功率因數(shù)校正

在LED照明技術(shù)日益普及的今天,LED驅(qū)動電源的電磁干擾(EMI)問題成為了一個(gè)不可忽視的挑戰(zhàn)。電磁干擾不僅會影響LED燈具的正常工作,還可能對周圍電子設(shè)備造成不利影響,甚至引發(fā)系統(tǒng)故障。因此,采取有效的硬件措施來解決L...

關(guān)鍵字: LED照明技術(shù) 電磁干擾 驅(qū)動電源

開關(guān)電源具有效率高的特性,而且開關(guān)電源的變壓器體積比串聯(lián)穩(wěn)壓型電源的要小得多,電源電路比較整潔,整機(jī)重量也有所下降,所以,現(xiàn)在的LED驅(qū)動電源

關(guān)鍵字: LED 驅(qū)動電源 開關(guān)電源

LED驅(qū)動電源是把電源供應(yīng)轉(zhuǎn)換為特定的電壓電流以驅(qū)動LED發(fā)光的電壓轉(zhuǎn)換器,通常情況下:LED驅(qū)動電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: LED 隧道燈 驅(qū)動電源
關(guān)閉