国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - C/C++ - C++20 新特性 協程 Coroutines(2)

C++20 新特性 協程 Coroutines(2)

2022-01-19 13:05孫孟越 C/C++

上篇文章簡單給大介紹了 C++20 特性 協程 Coroutines co_yield 和 co_return 那么這篇文章繼續給大家介紹C++20 的新特性協程 Coroutines co_await,需要的朋友可以參考一下

想了解上一篇文章內容的小伙伴可點擊 C++20 特性 協程 Coroutines (1)

談到什么是協程. 并且介紹了 co_yield co_return 的作用. 這篇來介紹一下 co_await.

1、co_await

一個形如:

?
1
co_await awaitable

的表達式就叫一個 await-expression. co_await 表達式是用來暫停當前協程的運行, 轉而等待 awaitable 的結果. 然后 awaitable 進行計算, 最終返回一個 awaiter 結構用來告訴 co_await 要做什么.

co_await 所在的函數塊本身就是協程, 所以這個 co_await 也得配上一個 promise 和一個 coroutine_handle. 就像上篇文章里面 generator 類之類的東西.

這個 awaitable 可以是很多東西, 首先會檢查 promise 有沒有提供 await_transform 函數, 如果有就會用上, 沒有就不管.

(只要提供了任何一個 await_transform, 那么每一個 awaitable 都需要找到適合它的重載, 否則就會報錯. 庫的實現者可以通過 await_transform 接口來限制哪些 awaitable 可以用在協程之中. 參見https://stackoverflow.com/q/65787797/14406396 )

之后的話, 會查找 operator co_await 這個函數, 預期這個 operator 返回一個 awaiter.已經是一個 awaiter 了.

2、awaiter 的三個接口用途

一個 awaiter 需要實現三個接口 await_ready() , await_suspend(std::coroutine_handle<P>) , await_resume() .

只要實現了這三個接口的東西就是 awaiter.

await_ready() 告訴 co_await 自己好了沒.

await_suspend(h) 可以選擇返回 void , bool , std::coroutine_handle<P> 之一. h 是本協程的 handle. P是本協程的 promise 類型 (或者是 void, 見第三篇中的解釋).

如果 await_ready() 返回 false , 這個協程就會暫停. 之后:

  • 如果 await_suspend(h) 返回類型是 std::coroutine_handle<Z>, 那么就會恢復這個 handle. 即運行 await_suspend(h).resume(). 這意味著暫停本協程的時候, 可以恢復另一個協程.
  • 如果 await_suspend(h) 返回類型是 bool, 那么看 await_suspend(h) 的結果, 是 false 就恢復自己.
  • 如果 await_suspend(h) 返回類型是 void, 那么就直接執行. 執行完暫停本協程.

如果 await_ready() 返回 true 或者協程被恢復了, 那么就執行 await_resume() , 它得到的結果就是最終結果.

所以說, 這await_ready, await_suspend, await_resume 三個接口分別表示 "有沒有準備好", "停不停", "好了該咋辦". 設計還是很自然的.

C++ 的協程是非對稱協程, 是有一個調用/被調用的關系的. 一個協程被某個東西喚醒了, 那么它下次暫停的時候, 就會把控制流還給那個喚醒它的東西. 所以 C++ 的協程完全可以看作是一個可重入的函數.

3、協程用法的回顧

再來看上一篇文章中的偽代碼

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
promise-type promise(promise-constructor-arguments);
try {
    co_await promise.initial_suspend(); // 創建之后 第一次暫停
    function-body // 函數體
} catch ( ... ) {
    if (!initial-await-resume-called)
    throw;
    promise.unhandled_exception();
}
 
final-suspend:
co_await promise.final_suspend(); // 最后一次暫停
}

catch 塊里面出現的 !initial-await-resume-called 就是指 promise.initial_suspend() 返回的那個 await_resume() 有沒有被執行過.

如果執行了, 那么這個 flag 就會立刻變成 true. 然后調用 promise.unhandled_exception() 來處理異常.

一個例子:

由于 co_await 對這三個東西的應該做什么沒有做任何限制, 所以可以用來實現很多功能.

舉個例子 (來自標準庫), 比如我們想要設計一個協程, 能夠停下任意的正時長, 就可以這樣設計:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
template <class Rep, class Period>
auto operator co_await(std::chrono::duration<Rep, Period> d) // operator co_await
{
    struct awaiter
    {
        std::chrono::system_clock::duration duration;
        awaiter(std::chrono::system_clock::duration d) : duration(d) {}
        bool await_ready() const { return duration.count() <= 0; }
        int await_resume() {  return 1;  }
        void await_suspend(std::coroutine_handle<> h)
        {
            std::this_thread::sleep_for(duration);
        }
    };
    return awaiterldzjh9fvzrv3;
}

這樣的話, 如果輸入一個正的時間, 就會調用 await_suspend() 進行暫停了. 如果輸入的時間是負的, 那就通過 await_ready() 返回 true 繞過了這個過程.

當然, 調用它需要在一個協程中, 也就意味著需要一個 promise coroutine_handle 包裝類的配合. 像這樣

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
struct my_future
{
    struct promise_type;
    using handle = std::coroutine_handle<promise_type>;
    struct promise_type
    {
        int current_value;
        auto initial_suspend() { return std::suspend_always{}; }
        auto final_suspend() { return std::suspend_always{}; }
        void unhandled_exception() { std::terminate(); }
        /* ... */
    };
    /* ... */
private:
    my_future(handle h) : coro(h) {}
    handle coro;
};
 
my_future sleep_coro()
{
    printf("Start sleeping\n");
    int ans = co_await 1s;
    printf("End sleeping, with ans = %d\n", ans);
}

當然, 一個函數也可以放在 co_await 的右邊, 就像 co_await g(); 只要返回的結構里面有那三個 await_* 接口就行. 甚至你可以直接 co_await std::suspend_always{};

下面是協程流控的細致分析.

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int main()
{
    auto h = sleep_coro();
// 這一步創建協程, 在 co_await initial_suspend 處, 執行完 await_ready, await_suspend. 返回 main
// 注意 initial_suspend 返回的是 std::suspend_always{}
// 所以是一定暫停, 并且 resume 的時候什么都不做
 
    h.resume();
// 這一步執行上一個 await_resume 以后(什么都不做), 執行了 printf("Start sleeping\n");
// 然后收到 co_await 1s 返回的結構, 其中 await_suspend 里面需要暫停.
// 然后執行完 await_ready, await_suspend (在這個函數里暫停 1s), 返回 main
 
    h.resume();
// 這一步執行完 await_resume 以后(初始化 ans = 1)
// 執行了 printf("End sleeping, with ans = %d\n", ans);
// 然后在 co_await final_suspend 處執行完 await_ready, await_suspend. 就返回 main
 
}

示列代碼見這里

到這里大家可以重新會到(1)去看看:C++20 特性 協程 Coroutines(1)

到此這篇關于C++20 新特性 協程 Coroutines(2)的文章就介紹到這了,更多相關C++20 協程 Coroutines內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!

原文鏈接:https://zhuanlan.zhihu.com/p/349710180

延伸 · 閱讀

精彩推薦
  • C/C++c++ 單線程實現同時監聽多個端口

    c++ 單線程實現同時監聽多個端口

    這篇文章主要介紹了c++ 單線程實現同時監聽多個端口的方法,幫助大家更好的理解和學習使用c++,感興趣的朋友可以了解下...

    源之緣11542021-10-27
  • C/C++C/C++經典實例之模擬計算器示例代碼

    C/C++經典實例之模擬計算器示例代碼

    最近在看到的一個需求,本以為比較簡單,但花了不少時間,所以下面這篇文章主要給大家介紹了關于C/C++經典實例之模擬計算器的相關資料,文中通過示...

    jia150610152021-06-07
  • C/C++C語言中炫酷的文件操作實例詳解

    C語言中炫酷的文件操作實例詳解

    內存中的數據都是暫時的,當程序結束時,它們都將丟失,為了永久性的保存大量的數據,C語言提供了對文件的操作,這篇文章主要給大家介紹了關于C語言中文件...

    針眼_6702022-01-24
  • C/C++詳解c語言中的 strcpy和strncpy字符串函數使用

    詳解c語言中的 strcpy和strncpy字符串函數使用

    strcpy 和strcnpy函數是字符串復制函數。接下來通過本文給大家介紹c語言中的strcpy和strncpy字符串函數使用,感興趣的朋友跟隨小編要求看看吧...

    spring-go5642021-07-02
  • C/C++C++之重載 重定義與重寫用法詳解

    C++之重載 重定義與重寫用法詳解

    這篇文章主要介紹了C++之重載 重定義與重寫用法詳解,本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內容,需要的朋友可以參考下...

    青山的青6062022-01-04
  • C/C++C語言實現電腦關機程序

    C語言實現電腦關機程序

    這篇文章主要為大家詳細介紹了C語言實現電腦關機程序,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    xiaocaidayong8482021-08-20
  • C/C++深入理解goto語句的替代實現方式分析

    深入理解goto語句的替代實現方式分析

    本篇文章是對goto語句的替代實現方式進行了詳細的分析介紹,需要的朋友參考下...

    C語言教程網7342020-12-03
  • C/C++學習C++編程的必備軟件

    學習C++編程的必備軟件

    本文給大家分享的是作者在學習使用C++進行編程的時候所用到的一些常用的軟件,這里推薦給大家...

    謝恩銘10102021-05-08
主站蜘蛛池模板: 尤物在线观看网站 | 成人av在线网站 | 亚洲社区在线 | 日韩一区在线播放 | 九九精品视频观看 | 亚洲毛片在线观看 | 亚洲欧美综合 | 中文字幕亚洲二区 | 国产欧美日韩三级 | 欧美在线观看一区 | 亚洲免费在线观看 | 亚洲视频三区 | 亚洲一区中文 | 国产精品一区视频 | 亚洲每日更新 | 成人在线观看免费视频 | 国产综合精品一区二区三区 | 中文字幕一区二区在线观看 | 日韩中文字幕视频 | 亚洲免费人成在线视频观看 | 黄色影视 | 激情五月婷婷综合 | 久久久一区二区 | 日韩中文一区二区三区 | 激情欧美一区二区三区中文字幕 | 夜夜视频| 亚洲国产精品一区 | 久久综合久久综合久久综合 | 日韩精品 电影一区 亚洲 | 欧美精品免费在线 | 国产中文字幕在线 | 日韩欧美一区二区中文字幕 | 免费av一区二区三区 | 国产脚交av在线一区二区 | 17c一起操 | 国产久精品| 中文字幕一区二区三区不卡 | 成人av片在线观看 | 日韩激情一区二区三区 | 四季久久免费一区二区三区四区 | 色吧一区|