2403C++,C++11玩轉無棧協程

原文

C++11里也能玩無棧協程了?

答案是:可以!
事實上異網在很早時,C++11里就可用無棧協程異步代碼了,只不過用起來不太方便,來看看C++11里怎么用異網無棧協程寫一個回音服務器的吧.

#包含 <異網.h++>
#包含 <內存>
#包含 <向量>
#包含 <異網/產生.h++>
用 異網::異步寫;
用 異網::緩沖;
用 異網::ip::傳控;
用 異網::錯誤碼;
用 大小型;
構 會話:異網::協程
{共針<傳控::套接字>套接字_;共針<向量<>>緩沖_;會話(共針<傳控::套接字> 套接字): 套接字_(套接字),緩沖_(新 向量<>(1024)){}空 符號()(錯誤碼 ec = 錯誤碼(), 大小型 n = 0){(!ec) 再入 (){(;;){產生 套接字_->異步讀些(緩沖(*緩沖_), *); 產生 異步寫(*套接字_, 緩沖(*緩沖_, n), *); }}}
};
構 服務器 : 異網::協程
{異網::io服務& io服務_;共針<傳控::受者> 受者_;共針<傳控::套接字> 套接字_;服務器(異網::io服務& io服務): io服務_(io服務),受者_(新 傳控::受者(io服務, 傳控::端點(傳控::v4(), 54321))){}空 符號()(錯誤碼 ec = 錯誤碼()){再入 (){(;;){套接字_.重置(新 傳控::套接字(io服務_));產生 受者_->異步接受(*套接字_, *);io服務_.提交(會話(套接字_));}}}
};
#包含 <異網/堅定.h++>
整 主()
{異網::io服務 io服務;io服務.提交(服務器(io服務));io服務.();
}

先看回聲會話部分的代碼:

  空 符號()(錯誤碼 ec = 錯誤碼(), 大小型 n = 0){(!ec) 再入 (){(;;){產生 套接字_->異步讀些(緩沖(*緩沖_), *); 產生 異步寫(*套接字_, 緩沖(*緩沖_, n), *); }}}
//其中(;;)
{產生 套接字_->異步讀些(緩沖(*緩沖_), *); 產生 異步寫(*套接字_, 緩沖(*緩沖_, n), *); 
} 

C++20協程代碼是不是很像:

(;;)
{協待 套接字_->異步讀些(緩沖(*緩沖_), 異網::用可等待); 協待 異步寫(*套接字_, 緩沖(*緩沖_, n), 異網::用可等待); 
} 

所以C++11里面也是可通過協程來寫異步代碼的.
但是異網無棧協程實現比較簡陋,使用起來有不少約束.首先要把用無棧協程文件兩個頭文件包裝起來,因為內部是實現的,編譯完之后需要解定義.

#包含 <異網/產生.h++>
#包含 <異網/堅定.h++>

第二個不便之處是不自由,使用協程的對象要從異網::協程繼承,然后定義符號,注意該符號是怎么寫的:

  空 符號()(錯誤碼 ec = 錯誤碼(), 大小型 n = 0){(!ec) 再入 (){(;;){產生 套接字_->異步讀些(緩沖(*緩沖_), *); 產生 異步寫(*套接字_, 緩沖(*緩沖_, n), *); }}}

相信你第一次看到該代碼時會很懵,這是個啥意思,再入是什么鬼,看不懂該代碼.不要著急,聽我來給你解惑該符號.
參數錯誤碼和傳輸大小,最開始時是默認的,為何這兩個參數呢?注意函數中的再入(本),它表明當前該函數可重入的,則何時會重入呢?

每次產生返回時就重入了,產生之后ec大小就是新的了.比如產生 套接字_->異步讀些(緩沖(*緩沖_),*本);
返回后,就可得到錯誤碼和讀到的大小了,所以完整寫法應該是:

  空 符號()(錯誤碼 ec = 錯誤碼(), 大小型 n = 0){(!ec) 再入 (){(;;){產生 套接字_->異步讀些(緩沖(*緩沖_), *);//協程重入(ec){輸出<< "讀錯誤消息: " << ec.消息() << "\n";;}輸出 << "讀大小: " << n << "\n";產生 異步寫(*套接字_, 緩沖(*緩沖_, n), *); //協程重入(ec){輸出<< "寫錯誤消息: " << ec.消息() << "\n";;}輸出<<"寫大小:"<<n<<"\n";}}}

現在看懂了,該怪異寫法了吧.
接著,如果想開啟新協程要怎么做,看服務器接受的代碼:

  空 符號()(錯誤碼 ec = 錯誤碼()){再入 (){(;;){套接字_.重置(新 傳控::套接字(io服務_));產生 受者_->異步接受(*套接字_, *);io服務_.提交(會話(套接字_));}}}

產生受者_->異步接受(*套接字_,*本);之后通過提交,把會話對象丟到io環境線程池中了,后續會執行該會話對象,此時,你可能有疑問,為啥可把對象丟到線程池里?

答案很簡單,因為會話符號它就成為一個函數對象了.

為什么這里要把會話函數對象丟到線程池里呢,為啥不繼續產生呢?因為這里想立即再次接受而不是等待會話結束,如果產生 會話那就沒辦法繼續接受了.
通過提交非阻塞方式調用會話的協程,兩個協程不會相互阻塞.
除此外,異網還提供了另外一個創建子協程的方法:

空 服務器::符號()(異網::錯誤碼 ec, 大小型 長度)
{(!ec){再入 (){{套接字_.重置(新 傳控::套接字(受者_->取執行器()));產生 受者_->異步接受(*套接字_, *);分叉 服務器(*)();//`分叉`之后父子協程都會往下執行到此}(是父());產生 套接字_->異步讀些(緩沖(*緩沖_), *); 產生 異步寫(*套接字_, 緩沖(*緩沖_, n), *); }}
}

異網可通過分叉來創建子協程,分叉之后父協程和子協程都會往下執行,那如何區分父子協程呢?通過是父()來區分.

父協程是接受協程,當走到是父()時,它會繼續接受,而子協程則會跳出循環,往下去了.

這就是通過分叉創建新協程的方法.

總結

異網里面有很多有趣的東西,以前還沒注意C++11里用可無棧協程異步代碼,也是其余遠調用維護時想用協程去改造,然后發現了該東西,它已有很久的歷史了,但我現在才注意到,確實能簡化編寫異步代碼,后面C++11版本的其余遠調用會使用異網無棧協程去寫.

不過寫法比使用C++20協程庫麻煩多了,但是考慮畢竟是C++11,能用協程已不錯了,如果能升級到20標準還是用20協程舒服.

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/711984.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/711984.shtml
英文地址,請注明出處:http://en.pswp.cn/news/711984.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

c++異常機制(5)-- 繼承與異常

我們在c異常機制(3)中自定義類型&#xff0c;我們將相應的異常封裝成了類&#xff0c;在類中實現一些方法&#xff0c;對異常進行處理。其中每一個類都實現了print()方法。 我們使用throw拋出相應異常的虛擬對象&#xff0c;在catch參數中進行匹配&#xff0c;但是如果有很多異…

Springboot項目集成短信驗證碼(超簡單)

操作流程 注冊驗證碼平臺創建驗證碼模版開始集成&#xff08;無需引入第三方庫&#xff09; 注冊并登陸中昱維信驗證碼平臺 獲取AppID和AppKey。 創建驗證碼模版 創建驗證碼模版&#xff0c;獲取驗證碼模版id 開始集成 創建controller import org.springframework.web.bi…

MATLAB環境下基于隨機游走拉普拉斯算子的快速譜聚類方法

古人有云&#xff0c;物以類聚&#xff0c;在面臨信息爆炸問題的今天&#xff0c;對信息類別劃分的價值日益顯現&#xff0c;并逐步成為學者們的研究熱點。分類和聚類是數據挖掘的重要工具&#xff0c;是實現事物類別劃分的左右手&#xff0c;聚類又是分類一種特殊的方式。所謂…

CodeWhisperer安裝教導--一步到位!以及本人使用Whisperer的初體驗。

CodeWhisperer是亞馬遜出品的一款基于機器學習的通用代碼生成器&#xff0c;可實時提供代碼建議。類似 Cursor 和Github AWS CodeWhisperer 亞馬遜科技的CodeWhisperer是Amazon于2021年12月推出的一款代碼補全工具&#xff0c;與GitHub Copilot類似。主要的功能有:代碼補全注釋…

貓毛過敏養貓人士的必備養貓好物-寵物空氣凈化器品牌分享

許多貓奴在與貓相處一段時間后突然對貓毛過敏&#xff0c;這真是令人難受。一些人認為對貓咪過敏是因為它們在空氣中飄浮的毛發引起的&#xff0c;但實際上大部分人之所以過敏是因為對貓身上一種微小的蛋白質過敏。這種導致過敏的蛋白質附著在貓咪的一些皮屑上。我們都知道貓咪…

前端架構: 腳手架通用框架封裝之入口文件開發(教程一)

腳手架入口文件開發 創建腳手架項目: abc-cli $ mkdir abc-cli && cd abc-cli 全局安裝 lerna, $ npm i -g lerna 基于 lerna 完成項目初始化 $ lerna init 基于 lerna 創建腳手架 cli $ lerna create cli一路回車 好現在生成了一個 cli 的模板&#xff0c;目前需要…

Qt 中Json的構造和解析簡單例子

概述: Qt中使用Json比較方便&#xff0c;不像純C需要導入CJson RapidJson JsonCpp等第三方的庫&#xff0c;主要使用到QJsonDocument、QJsonObject對象即可 1、如何構造一個json字符串 假如我們需要構造 {"cmd":"1001","data":{"content&q…

Linux 下安裝Jupyter

pip3 install jupyter pip3 install ipython -------------------------------------------- pip3 install jupyterlab jupyter lab pip3 list | grep jupyterlab 啟動&#xff1a; python3 -m jupyter lab 2.安裝朱皮特 pip3 install -i https://pypi.douban.com/simpl…

高性能的key-value數據庫Redis 介紹

Redis 是一個高性能的key-value數據庫。 Redis是一個開源的鍵值存儲系統&#xff0c;通常用于緩存和消息傳遞。它支持多種類型的數據結構&#xff0c;如字符串、列表、集合、散列表和有序集合等。Redis的特點是提供了高性能、靈活性和可伸縮性。 Redis的主要特點包括&#xff…

Pytorch學習 day02(加載數據)

加載數據 * Dataset提供一種方式&#xff1a;來獲取數據及其label&#xff0c;給數據進行編號 * Dataloader為神經網絡提供不同的數據形式 Dataset的組織形式有很多種&#xff0c;例如&#xff1a; 將label放在文件夾名上&#xff0c;如下&#xff1a; #Dateset # --train #…

Python算法題集_組合總和

Python算法題集_組合總和 題39&#xff1a;組合總和1. 示例說明2. 題目解析- 題意分解- 優化思路- 測量工具 3. 代碼展開1) 標準求解【值傳遞回溯】2) 改進版一【引用傳遞堆棧回溯】3) 改進版二【過程值列表緩存遍歷后檢索】 4. 最優算法5. 相關資源 本文為Python算法題集之一的…

.halo勒索病毒的最新威脅:如何恢復您的數據?

尊敬的讀者&#xff1a; 隨著科技的發展&#xff0c;網絡安全已經成為我們日常生活中不可忽視的重要議題。其中&#xff0c;勒索病毒是當前網絡安全威脅中的一大挑戰&#xff0c;而“.halo”勒索病毒更是近期備受關注的惡意軟件之一。本文將介紹關于“.halo”勒索病毒的背景知…

AI新工具(20240227) StickerBaker文本生成貼紙的工具;Mistral Large;Rewind等

StickerBaker - 基于Replicate和Fly.io技術&#xff0c;100%開源的制作貼紙的工具 StickerBaker是一個基于人工智能的貼紙創作工具&#xff0c;允許用戶通過輸入特定的提示語句生成獨特的貼紙。這個工具使用了Replicate平臺來生成貼紙&#xff0c;同時依托于Fly.io作為其基礎設…

算法項目外包的收費方式

針對算法研究性項目的收費方式和注意事項&#xff0c;這取決于項目的具體性質、規模和所涉及的技術領域。以下是一些常見的收費方式和需要注意的問題&#xff0c;希望對大家有所幫助。北京木奇移動技術有限公司&#xff0c;專業的軟件外包開發公司&#xff0c;歡迎交流合作。 收…

Python學習DAY09_文件和異常

文件和異常 實際開發中常常會遇到對數據進行持久化操作的場景&#xff0c;而實現數據持久化最直接簡單的方式就是將數據保存到文件中。 在 Python 中實現文件的讀寫操作其實非常簡單&#xff0c;通過 Python 內置的 open 函數&#xff0c;我們可以指定文件名、操作模式、編碼信…

1552.平衡二叉樹

輸入格式 第一行包含整數 N&#xff0c;表示總插入值數量。第二行包含 N 個不同的整數&#xff0c;表示每個插入值。 輸出格式 輸出得到的 AVL 樹的根是多少。 數據范圍 1≤N≤20 輸入樣例1&#xff1a; 5 88 70 61 96 120 輸出樣例1&#xff1a; 70 輸入樣例2&#xff1a…

商業江湖大揭秘:月入千萬與顆粒無收,究竟差了什么?

在商業的浩瀚江湖 英雄豪杰們或乘風破浪、月入千萬&#xff0c;或步履蹣跚、顆粒無收&#xff0c;這背后的奧秘究竟何在&#xff1f;是天意難測&#xff0c;還是人為疏忽&#xff1f;是制度的不完善&#xff0c;還是工具的滯后不前&#xff1f;答案就隱藏在你未曾注意的細節之…

公司招嵌入式開發崗位,為什么感覺一年比一年難?

最近看到一個問題&#xff1a; 是一個HR在吐槽招不到嵌入式開發的人才。 這句話&#xff0c;難免會誤導一些想入行嵌入式的同學&#xff0c;臥槽&#xff0c;這么缺人?趕緊沖&#xff01; 哼次哼次學完一堆技術棧&#xff0c;一投簡歷&#xff0c;一個面試機會都沒有。 這就是…

24路電磁鎖主板在智能存儲系統中的作用

在無人值守場景中&#xff0c;如自助服務機、智能生鮮柜、共享儲物柜等&#xff0c;使用24路電磁鎖主板可以集成身份識別技術&#xff0c;將用戶的驗證結果轉化為相應的開鎖動作&#xff0c;提升用戶體驗和運營效率&#xff0c;是實現智能存儲系統高效、安全和自動化運行的關鍵…

Kubernetes的五大開源存儲項目

在Kubernetes中&#xff0c;關于數據的持久化管理是一種挑戰&#xff0c;對此&#xff0c;社區提供了多種存儲的解決方案&#xff0c;這些方案旨在簡化和優化容器化應用程序的持久化數據管理。 現介紹 Kubernetes 的五大開源存儲項目&#xff0c;帶你了解開源存儲解決方案的多…