成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

C++ 20 協程 Coroutine之剖析

開發 前端
C++20協程在啟動前,開始會new 一個協程狀態(coroutine state?)。然后構造協程的承諾對象(promise?)。承諾對象(promise?)通過get_return_object()?構造協程的返回值result?。

我們來剖析一下協程的過程。通過這個剖析,希望達到梳理協程幾個重要概念的關系,把這些點串起來。所以在概念參考我們列出了相應的概念文字。

協程的創建

C++20協程在啟動前,開始會new 一個協程狀態(coroutine state?)。然后構造協程的承諾對象(promise?)。承諾對象(promise?)通過get_return_object()?構造協程的返回值result?。這個返回值在協程第一次掛起時,賦值給調用者。然后通過co_await promise.initial_suspend()?,決定協程初試完成后的行為。如果返回std::suspend_always?,初始化就掛起,如果返回std::suspend_never ,初始化后就繼續運行。(注意initial_suspend也可以返回其他協程體)

圖片

協程的co_await

cw_ret = co_await awaiter? 或者cw_ret = co_await fun()?,先計算表達式fun,fun返回結果,就是一個等待體awaiter?。系統先調用awaiter.await_ready()?接口,看等待體是否準備好了,沒準備好(return false?)就調用awaiter.await_suspend()。await_suspend?根據參數可以記錄調用其的協程的的句柄。await_suspend?的返回值為return true? ,或者 return void 就會掛起協程。

后面在外部如果恢復了協程的運行,awaiter.await_resume()?接口被調用。其返回結果,作為co_await的返回值。

圖片

協程的co_yield

co_yield cy_ret;?,相當于調用co_wait promise.yield_value(cy_ret)?,你可以在yield_value?中記錄參數cy_ret?后面使用,yield_value?的返回值如果是std::suspend_always?,協程掛起,如果返回std::suspend_never ,協程就繼續運行。

圖片

協程的co_return

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

圖片

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

概念參考附錄:

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

協程狀態(coroutine state)

協程狀態(coroutine state)是協程啟動開始時,new空間存放協程狀態,協程狀態記錄協程函數的參數,協程的運行狀態,變量。掛起時的斷點。

注意,協程狀態 (coroutine state?)并不是就是協程函數的返回值RET。雖然我們設計的RET一般里面也有promise和coroutine handle?,大家一般也是通過RET去操作協程的恢復,獲取返回值。但coroutine state?理論上還應該包含協程運行參數,斷點等信息。而協程狀態 (coroutine state?)應該是協程句柄(coroutine handle)對應的一個數據,而由系統管理的。

承諾對象(promise)

承諾對象的表現形式必須是result::promise_type,result為協程函數的返回值。

承諾對象是一個實現若干接口,用于輔助協程,構造協程函數返回值;提交傳遞co_yield,co_return的返回值。明確協程啟動階段是否立即掛起;以及協程內部發生異常時的處理方式。其接口包括:

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

前面我們提到在協程創建的時候,會new協程狀態(coroutine state?)。你可以通過可以在 promise_type? 中重載 operator new? 和 operator delete,使用自己的內存分配接口。(請參考再探 C++20 協程)

協程句柄(coroutine handle)

協程句柄(coroutine handle)是一個協程的標示,用于操作協程恢復,銷毀的句柄。

協程句柄的表現形式是std::coroutine_handle<promise_type>?,其模板參數為承諾對象(promise)類型。句柄有幾個重要函數:

  • resume()函數可以恢復協程。
  • done()函數可以判斷協程是否已經完成。返回false標示協程還沒有完成,還在掛起。

協程句柄和承諾對象之間是可以相互轉化的。

  • std::coroutine_handle<promise_type>::from_promise :這是一個靜態函數,可以從承諾對象(promise)得到相應句柄。
  • std::coroutine_handle<promise_type>::promise() 函數可以從協程句柄coroutine handle得到對應的承諾對象(promise)

等待體(awaiter)

co_wait 關鍵字會調用一個等待體對象(awaiter)。這個對象內部也有3個接口。根據接口co_wait  決定進行什么操作。

  • bool await_ready():等待體是否準備好了,返回 false ,表示協程沒有準備好,立即調用await_suspend。返回true,表示已經準備好了。
  • auto await_suspend(std::coroutine_handle<> handle)如果要掛起,調用的接口。其中handle參數就是調用等待體的協程,其返回值有3種可能

void 同返回true

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

返回某個協程句柄(coroutine handle),立即恢復對應句柄的運行。

  • auto await_resume() :協程掛起后恢復時,調用的接口。返回值作為co_wait 操作的返回值。

等待體(awaiter)值得用更加詳細的筆墨書寫一章,我們就放一下,先了解其有2個特化類型。

  • std::suspend_never類,不掛起的的特化等待體類型。
  • std::suspend_always類,掛起的特化等待體類型。

前面不少接口已經用了這2個特化的類,同時也可以明白其實協程內部不少地方其實也在使用co_wait 關鍵字。

本章總結

此章講解了協程的啟動,3個關鍵字的細節。您可以通過這些關鍵概念,融合協程狀態(coroutine state?),承諾對象(promise?),協程句柄(coroutine handle?),等待體(awaiter)。

參考文檔

初探 C++20 協程

再探 C++20 協程

Coroutines (C++20)

協程(coroutine)簡介

The Coroutine in C++ 20 協程之諾

C++ Coroutines: Understanding operator co_await

責任編輯:武曉燕 來源: 碼磚雜役
相關推薦

2022-09-06 20:30:48

協程Context主線程

2022-09-10 18:51:09

C++協程主線程

2023-11-04 20:00:02

C++20協程

2013-12-12 16:44:25

Lua協程

2025-06-26 04:10:00

2024-09-25 08:28:45

2025-06-26 02:00:00

2021-05-20 09:14:09

Kotlin協程掛起和恢復

2021-09-16 09:59:13

PythonJavaScript代碼

2010-01-14 17:42:47

CC++

2021-08-04 16:19:55

AndroidKotin協程Coroutines

2010-01-28 16:31:54

C++類型

2023-11-17 11:36:59

協程纖程操作系統

2023-07-13 08:06:05

應用協程阻塞

2021-02-19 06:56:33

架構協程應用

2022-07-18 15:32:37

C++虛函數表

2010-02-06 16:05:51

C++ Vector

2024-12-24 15:02:10

2023-10-24 19:37:34

協程Java

2025-02-08 09:13:40

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 亚洲成人精品国产 | 日韩精品 电影一区 亚洲 | 男人的天堂久久 | av在线一区二区三区 | 欧美一级黄带 | 在线欧美激情 | 伊久在线| 亚洲成网| 国产免费福利 | 日本午夜一区二区三区 | 在线色网 | 嫩草影院黄| 欧美aaaaaaaaaa| 亚洲最大福利网 | 亚洲欧美激情精品一区二区 | 亚洲一二三区av | 亚洲一区二区三区四区在线观看 | 男插女下体视频 | 亚洲成人黄色 | 久久综合九九 | 日韩福利在线观看 | 91成人免费电影 | 日本一区二区高清视频 | av片在线播放 | 91一区 | 久久tv在线观看 | 91在线电影 | 一区二区三区日韩精品 | 久久久在线视频 | 亚洲一二三区精品 | 综合五月婷 | 国产美女一区二区 | 国产观看| 国产一区二区a | 亚洲激情一级片 | 精品丝袜在线 | 成人在线不卡 | 欧美一级二级在线观看 | 亚洲精品一区在线观看 | 亚洲一区视频在线 | 免费小视频在线观看 |