自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

C++ 20 協(xié)程 Coroutine之剖析

開(kāi)發(fā) 前端
C++20協(xié)程在啟動(dòng)前,開(kāi)始會(huì)new 一個(gè)協(xié)程狀態(tài)(coroutine state?)。然后構(gòu)造協(xié)程的承諾對(duì)象(promise?)。承諾對(duì)象(promise?)通過(guò)get_return_object()?構(gòu)造協(xié)程的返回值result?。

我們來(lái)剖析一下協(xié)程的過(guò)程。通過(guò)這個(gè)剖析,希望達(dá)到梳理協(xié)程幾個(gè)重要概念的關(guān)系,把這些點(diǎn)串起來(lái)。所以在概念參考我們列出了相應(yīng)的概念文字。

協(xié)程的創(chuàng)建

C++20協(xié)程在啟動(dòng)前,開(kāi)始會(huì)new 一個(gè)協(xié)程狀態(tài)(coroutine state?)。然后構(gòu)造協(xié)程的承諾對(duì)象(promise?)。承諾對(duì)象(promise?)通過(guò)get_return_object()?構(gòu)造協(xié)程的返回值result?。這個(gè)返回值在協(xié)程第一次掛起時(shí),賦值給調(diào)用者。然后通過(guò)co_await promise.initial_suspend()?,決定協(xié)程初試完成后的行為。如果返回std::suspend_always?,初始化就掛起,如果返回std::suspend_never ,初始化后就繼續(xù)運(yùn)行。(注意initial_suspend也可以返回其他協(xié)程體)

圖片

協(xié)程的co_await

cw_ret = co_await awaiter? 或者cw_ret = co_await fun()?,先計(jì)算表達(dá)式fun,fun返回結(jié)果,就是一個(gè)等待體awaiter?。系統(tǒng)先調(diào)用awaiter.await_ready()?接口,看等待體是否準(zhǔn)備好了,沒(méi)準(zhǔn)備好(return false?)就調(diào)用awaiter.await_suspend()。await_suspend?根據(jù)參數(shù)可以記錄調(diào)用其的協(xié)程的的句柄。await_suspend?的返回值為return true? ,或者 return void 就會(huì)掛起協(xié)程。

后面在外部如果恢復(fù)了協(xié)程的運(yùn)行,awaiter.await_resume()?接口被調(diào)用。其返回結(jié)果,作為co_await的返回值。

圖片

協(xié)程的co_yield

co_yield cy_ret;?,相當(dāng)于調(diào)用co_wait promise.yield_value(cy_ret)?,你可以在yield_value?中記錄參數(shù)cy_ret?后面使用,yield_value?的返回值如果是std::suspend_always?,協(xié)程掛起,如果返回std::suspend_never ,協(xié)程就繼續(xù)運(yùn)行。

圖片

協(xié)程的co_return

co_yield cr_ret;?,調(diào)用promise.retun_value(cr_ret)?,如果沒(méi)有返回值相當(dāng)于promise.retun_viod()?,你可以在retun_value?中記錄參數(shù)cr_ret?后面使用。然后調(diào)用co_await promise.final_suspend(void)?,如果返回值是std::suspend_always?,你需要自己手動(dòng)青清理coroutine handle?,調(diào)用handle.destroy()。

圖片

這兒存在一個(gè)疑問(wèn),final_suspend?,并沒(méi)有真正掛起協(xié)程??碈++ 參考,里面說(shuō)的也是calls promise.final_suspend() and co_awaits the result.?。按說(shuō)如果返回應(yīng)該要掛起。但用VS 2022測(cè)試是不會(huì)掛起的,再探 C++20 協(xié)程文章中說(shuō)的是如果返回std::suspend_always?,需要你自己清理coroutine handle。存疑吧。

概念參考附錄:

這些概念在原文第一章都有,附錄在此僅供您方便參考。

協(xié)程狀態(tài)(coroutine state)

協(xié)程狀態(tài)(coroutine state)是協(xié)程啟動(dòng)開(kāi)始時(shí),new空間存放協(xié)程狀態(tài),協(xié)程狀態(tài)記錄協(xié)程函數(shù)的參數(shù),協(xié)程的運(yùn)行狀態(tài),變量。掛起時(shí)的斷點(diǎn)。

注意,協(xié)程狀態(tài) (coroutine state?)并不是就是協(xié)程函數(shù)的返回值RET。雖然我們?cè)O(shè)計(jì)的RET一般里面也有promise和coroutine handle?,大家一般也是通過(guò)RET去操作協(xié)程的恢復(fù),獲取返回值。但coroutine state?理論上還應(yīng)該包含協(xié)程運(yùn)行參數(shù),斷點(diǎn)等信息。而協(xié)程狀態(tài) (coroutine state?)應(yīng)該是協(xié)程句柄(coroutine handle)對(duì)應(yīng)的一個(gè)數(shù)據(jù),而由系統(tǒng)管理的。

承諾對(duì)象(promise)

承諾對(duì)象的表現(xiàn)形式必須是result::promise_type,result為協(xié)程函數(shù)的返回值。

承諾對(duì)象是一個(gè)實(shí)現(xiàn)若干接口,用于輔助協(xié)程,構(gòu)造協(xié)程函數(shù)返回值;提交傳遞co_yield,co_return的返回值。明確協(xié)程啟動(dòng)階段是否立即掛起;以及協(xié)程內(nèi)部發(fā)生異常時(shí)的處理方式。其接口包括:

  • auto get_return_object() :用于生成協(xié)程函數(shù)的返回對(duì)象。
  • auto initial_suspend():用于明確初始化后,協(xié)程函數(shù)的執(zhí)行行為,返回值為等待體(awaiter),用co_wait調(diào)用其返回值。返回值為std::suspend_always 表示協(xié)程啟動(dòng)后立即掛起(不執(zhí)行第一行協(xié)程函數(shù)的代碼),返回std::suspend_never 表示協(xié)程啟動(dòng)后不立即掛起。(當(dāng)然既然是返回等待體,你可以自己在這兒選擇進(jìn)行什么等待操作)
  • void return_value(T v):調(diào)用co_return v后會(huì)調(diào)用這個(gè)函數(shù),可以保存co_return的結(jié)果
  • auto yield_value(T v):調(diào)用co_yield后會(huì)調(diào)用這個(gè)函數(shù),可以保存co_yield的結(jié)果,其返回其返回值為std::suspend_always表示協(xié)程會(huì)掛起,如果返回std::suspend_never表示不掛起。
  • auto final_suspend() noexcept:在協(xié)程退出是調(diào)用的接口,返回std::suspend_never ,自動(dòng)銷(xiāo)毀 coroutine state 對(duì)象。若 final_suspend 返回 std::suspend_always 則需要用戶(hù)自行調(diào)用 handle.destroy() 進(jìn)行銷(xiāo)毀。但值得注意的是返回std::suspend_always并不會(huì)掛起協(xié)程。

前面我們提到在協(xié)程創(chuàng)建的時(shí)候,會(huì)new協(xié)程狀態(tài)(coroutine state?)。你可以通過(guò)可以在 promise_type? 中重載 operator new? 和 operator delete,使用自己的內(nèi)存分配接口。(請(qǐng)參考再探 C++20 協(xié)程)

協(xié)程句柄(coroutine handle)

協(xié)程句柄(coroutine handle)是一個(gè)協(xié)程的標(biāo)示,用于操作協(xié)程恢復(fù),銷(xiāo)毀的句柄。

協(xié)程句柄的表現(xiàn)形式是std::coroutine_handle<promise_type>?,其模板參數(shù)為承諾對(duì)象(promise)類(lèi)型。句柄有幾個(gè)重要函數(shù):

  • resume()函數(shù)可以恢復(fù)協(xié)程。
  • done()函數(shù)可以判斷協(xié)程是否已經(jīng)完成。返回false標(biāo)示協(xié)程還沒(méi)有完成,還在掛起。

協(xié)程句柄和承諾對(duì)象之間是可以相互轉(zhuǎn)化的。

  • std::coroutine_handle<promise_type>::from_promise :這是一個(gè)靜態(tài)函數(shù),可以從承諾對(duì)象(promise)得到相應(yīng)句柄。
  • std::coroutine_handle<promise_type>::promise() 函數(shù)可以從協(xié)程句柄coroutine handle得到對(duì)應(yīng)的承諾對(duì)象(promise)

等待體(awaiter)

co_wait 關(guān)鍵字會(huì)調(diào)用一個(gè)等待體對(duì)象(awaiter)。這個(gè)對(duì)象內(nèi)部也有3個(gè)接口。根據(jù)接口co_wait  決定進(jìn)行什么操作。

  • bool await_ready():等待體是否準(zhǔn)備好了,返回 false ,表示協(xié)程沒(méi)有準(zhǔn)備好,立即調(diào)用await_suspend。返回true,表示已經(jīng)準(zhǔn)備好了。
  • auto await_suspend(std::coroutine_handle<> handle)如果要掛起,調(diào)用的接口。其中handle參數(shù)就是調(diào)用等待體的協(xié)程,其返回值有3種可能

void 同返回true

bool 返回true 立即掛起,返回false 不掛起。

返回某個(gè)協(xié)程句柄(coroutine handle),立即恢復(fù)對(duì)應(yīng)句柄的運(yùn)行。

  • auto await_resume() :協(xié)程掛起后恢復(fù)時(shí),調(diào)用的接口。返回值作為co_wait 操作的返回值。

等待體(awaiter)值得用更加詳細(xì)的筆墨書(shū)寫(xiě)一章,我們就放一下,先了解其有2個(gè)特化類(lèi)型。

  • std::suspend_never類(lèi),不掛起的的特化等待體類(lèi)型。
  • std::suspend_always類(lèi),掛起的特化等待體類(lèi)型。

前面不少接口已經(jīng)用了這2個(gè)特化的類(lèi),同時(shí)也可以明白其實(shí)協(xié)程內(nèi)部不少地方其實(shí)也在使用co_wait 關(guān)鍵字。

本章總結(jié)

此章講解了協(xié)程的啟動(dòng),3個(gè)關(guān)鍵字的細(xì)節(jié)。您可以通過(guò)這些關(guān)鍵概念,融合協(xié)程狀態(tài)(coroutine state?),承諾對(duì)象(promise?),協(xié)程句柄(coroutine handle?),等待體(awaiter)。

參考文檔

初探 C++20 協(xié)程

再探 C++20 協(xié)程

Coroutines (C++20)

協(xié)程(coroutine)簡(jiǎn)介

The Coroutine in C++ 20 協(xié)程之諾

C++ Coroutines: Understanding operator co_await

責(zé)任編輯:武曉燕 來(lái)源: 碼磚雜役
相關(guān)推薦

2022-09-06 20:30:48

協(xié)程Context主線程

2022-09-10 18:51:09

C++協(xié)程主線程

2023-11-04 20:00:02

C++20協(xié)程

2013-12-12 16:44:25

Lua協(xié)程

2024-09-25 08:28:45

2021-05-20 09:14:09

Kotlin協(xié)程掛起和恢復(fù)

2021-09-16 09:59:13

PythonJavaScript代碼

2010-01-14 17:42:47

CC++

2021-08-04 16:19:55

AndroidKotin協(xié)程Coroutines

2010-01-28 16:31:54

C++類(lèi)型

2023-11-17 11:36:59

協(xié)程纖程操作系統(tǒng)

2023-07-13 08:06:05

應(yīng)用協(xié)程阻塞

2021-02-19 06:56:33

架構(gòu)協(xié)程應(yīng)用

2022-07-18 15:32:37

C++虛函數(shù)表

2010-02-06 16:05:51

C++ Vector

2024-12-24 15:02:10

2014-02-11 09:28:57

2025-02-08 09:13:40

2023-10-24 19:37:34

協(xié)程Java

2021-12-09 06:41:56

Python協(xié)程多并發(fā)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)