2308C++簡單異步改造網絡庫

簡單異步可以輕松改造同步網絡庫從而獲得大幅性能提升,用它改造異步回調網絡庫可以讓我們以同步方式寫代碼,讓代碼更簡潔,可讀性更好,還能避免回調地獄的問題.
本文通過兩個例子分別來介紹如何用簡單異步改造基于asio的同步網絡庫和異步回調網絡庫.

示例依賴了獨立版的asio(commitid:f70f65ae54351c209c3a24704624144bfe8e70a3),它是headeronly的直接包含頭文件即可.

改造同步網絡庫

以一個同步的echo server/client為例,先來看看echoserver:

空 開始服務器(異網::io環境&io環境,正 短 端口){傳控::受者 a(io環境,傳控::端點(傳控::v4(),端口));(;;){[錯誤,套接字]=接受(a);會話(::移動(套接字));}
}

echoserver啟動時先監聽端口,然后同步accept,當有新連接到來時在會話中處理網絡讀寫事件.

<型名 異網緩沖>::<異網::錯誤碼,大小型>讀些(異網::ip::傳控::套接字&套接字, 異網緩沖&&緩沖){異網::錯誤碼 錯誤;大小型 長度=套接字.讀些(::前向<異網緩沖>(緩沖),錯誤);中 標::造雙(錯誤,長度);
}空 會話(傳控::套接字 套接字){(;;){常 大小型 最大長度=1024;符 數據[最大長度];[錯誤,長度]=讀些(套接字,數據,最大長度);(套接字,數據,長度);}
}

循環中先同步讀數據,再把讀到的數據發送到對端.

同步的echo client:

空 開始(異網::io環境&io環境,::串 主機,::串 端口){[ec,套接字]=連接(io環境,主機,端口);常 整 最大長度=1024;符 寫緩沖[最大長度]={"你好 簡單異步"};符 讀緩沖[最大長度];常 整 數=10000;(整 i=0;i<;++i){(套接字,寫緩沖,最大長度);[錯誤,回復長度]=讀些(套接字,讀緩沖,最大長度);//處理數據.}
}

同步的echoclient也是類似的過程,先連接,再循環發送數據和讀數據.整個邏輯都是同步的,代碼簡單易懂.

當然,因為整個過程都是同步等待的,所以無法并發的處理網IO事件,性能是比較差的.如果用簡單異步來改造這個同步的網絡庫則可以大幅提升網絡庫的性能(參考benchmark),而且需要修改的代碼很少,這就是簡單異步的威力.

簡單異步改造同步echoserver

簡單異步::協程::<>會話(傳控::套接字 套接字){(;;){常 大小型 最大長度=1024;符 數據[最大長度];[錯誤,長度]=協待 異步讀些(套接字,異網::緩沖(數據,最大長度));協待 異步寫(套接字,異網::緩沖(數據,長度));}::錯誤碼 ec;套接字.關閉(異網::ip::傳控::套接字::都關閉,ec);套接字.關閉(ec);::輸出<<"完成回聲消息,總:"<<消息索引-1<<".\n";
}簡單異步::協程::<>開始服務器(異網::io環境&io環境, 正 短 端口, 簡單異步::執行器*E){傳控::受者 a(io環境,傳控::端點(傳控::v4(),端口));(;;){[錯誤,套接字]=協待 異步接受(a);會話(::移動(套接字)).通過(E).開始([](&&){});}
}

可以看到用簡單異步改造的start_server會話相比,返回類型變成了Lazy,同步接口變成了co_await async_xxx,原有的同步邏輯沒有任何變化,這個微小的改動即可讓我們把同步網絡庫改成異步協程網絡庫從而讓性能得到巨大的提升.

更多的代碼細節請看demo_exampleechoserver/client的例子.

改造異步回調網絡庫

對于一些已有的異步回調網絡庫,也可以用簡單異步來消除回調,從而讓我們可以用同步方式去使用異步接口,讓代碼變得更簡潔易懂.

asio異步httpserver為例:

空 連接::干讀()
{動 本(從本共享());套接字_.異步讀些(異網::緩沖(緩沖_),[,](::錯誤碼 ec,::大小型 傳輸字節){(!ec){請求解析器::結果類型 結果;::綁定(結果,::忽略)=請求解析器_.解析(請求_,緩沖_.數據(),緩沖_.數據()+傳輸字節);(結果==請求解析器::){請求處理器_.請求處理(請求_,回復_);干寫();}異 如(結果==請求解析器::){回復_=回復::回復股票(回復::壞請求);干寫();}{干讀();}}異 如(ec!=異網::錯誤::中止操作){連接管_.停止(從本共享());}});
}空 連接::干寫()
{動 本(從本共享());異網::異步寫(套接字_,回復_.到緩沖(),[,](::錯誤碼 ec,::大小型){(!ec){異網::錯誤碼 忽略誤碼;套接字_.關閉(異網::ip::傳控::套接字::都關閉, 忽略誤碼);}(ec!=異網::錯誤::中止操作){連接管_.停止(從本共享());}});
}

可以看到基于回調的異步網絡庫的代碼,比同步網絡庫復雜很多,如在異步讀的回調中如果沒有讀到完整數據需要遞歸調用do_read,如果讀到完整數據之后才能在回調中調用異步寫接口.同時,還要注意將shared_from_this()得到的std::shared_ptr傳入到異步接口的回調函數中以保證安全的回調.總之,異步回調代碼的編寫難度較大,可讀性也較差,如果用簡單異步改造則可以較好的解決這些問題,性能也不會降低.

簡單異步改造異步httpserver

簡單異步::協程::<>干讀(){動 本(從本共享());(;;){[錯誤,傳輸字節]=協待 異步讀些(套接字_,異網::緩沖(讀緩沖_));(錯誤){;}請求解析器::結果類型 結果;::綁定(結果,::忽略)=解析器_.解析(請求_,讀緩沖_,讀緩沖_+傳輸字節);(結果==請求解析器::){請求處理(請求_,響應_);協待 異步寫(套接字_,響應_.到緩沖());}異 如(結果==請求解析器::){響應_=構建響應(狀態類型::壞請求);協待 異步寫(套接字_,響應_.到緩沖());;}}
}

簡單異步改造之后的httpserver完全消除了回調函數,完全可按同步方式寫異步代碼,簡潔易懂.
測試結果,提高2倍速度!

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

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

相關文章

JavaWeb_總體介紹

文章目錄 1.總括2.JavaWeb項目架構 1.總括 2.JavaWeb項目架構

request.post,json和data

參考 https://zhuanlan.zhihu.com/p/140372568 https://zhuanlan.zhihu.com/p/140372568 介紹 這兩條請求語句使用了不同的參數傳遞方式&#xff0c;有以下區別&#xff1a;1. requests.post(urlhttp://xx.8.84.xx:8000/inference, jsondata)這個語句使用了 json 參數&#…

js設置css變量控制頁面一行展示指定個數的元素

前置知識&#xff1a; CSS變量之var()函數的應用——動態修改樣式 & root的使用 flex相關知識 場景&#xff1a; 動態設置給父元素內子元素設置每行排列幾個 通過 document.body.style.setProperty(--itemNum, 5)設置樣式變量&#xff0c;然后通過給父元素設置display: f…

RocketMQ發送消息失敗:error CODE: 14 DESC: service not available now, maybe disk full

在執行業務時&#xff0c;發現MQ控制臺沒有查詢到消息&#xff0c;在日志中發現消息發送失敗&#xff0c;報錯error CODE: 14 DESC: service not available now, maybe disk full 分析報錯應該是磁盤空間不足&#xff0c;導致broker不能進行正常的消息存儲刷盤&#xff0c;去查…

MySQL 窗口函數是什么,有這么好用

先看這段像天書一樣的 SQL ,看著就頭疼。 SELECTs1.name,s1.subject,s1.score,sub.avg_score AS average_score_per_subject,(SELECT COUNT(DISTINCT s2.score) 1 FROM scores s2 WHERE s2.score > s1.score) AS score_rank FROM scores s1 JOIN (SELECT subject, AVG(sco…

Android 13 MTK平臺添加自定義按鍵,以及CTS問題解決

添加自定義按鍵流程 一般來說上層添加以下幾處修改 驅動層的鍵值上報,讓驅動處理好即可 frameworks / base/core/java/android/view/KeyEvent.java public static final int KEYCODE_DEMO_APP_4 = 304;/** add by songhui for fingerprint Key code */+ public static fina…

IntelliJ IDEA Bookmark使用

1 增加 右鍵行號欄 2 查看 從favorite這里查看 參考IntelliJ IDEA 小技巧&#xff1a;Bookmark(書簽)的使用_bookmark idea 使用_大唐冠軍侯的博客-CSDN博客

neo4j的CQL命令實例演示

天行健&#xff0c;君子以自強不息&#xff1b;地勢坤&#xff0c;君子以厚德載物。 每個人都有惰性&#xff0c;但不斷學習是好好生活的根本&#xff0c;共勉&#xff01; 文章均為學習整理筆記&#xff0c;分享記錄為主&#xff0c;如有錯誤請指正&#xff0c;共同學習進步。…

07-2_Qt 5.9 C++開發指南_二進制文件讀寫(stm和dat格式)

文章目錄 1. 實例功能概述2. Qt預定義編碼文件的讀寫2.1 保存為stm文件2.2 stm文件格式2.3 讀取stm文件 3. 標準編碼文件的讀寫3.1 保存為dat文件3.2 dat文件格式3.3 讀取dat文件 4. 框架及源碼4.1 可視化UI設計4.2 mainwindow.cpp 1. 實例功能概述 除了文本文件之外&#xff…

pve和openwrt以及我的電腦中網絡的關系和互通組網

情況1 一臺主機 有4個口&#xff0c;分別eth0,eth1,eth2,eth3 pve有管理口 這個情況下 &#xff0c;沒有openwrt 直接電腦和pve管理口連在一起就能進pve管理界面 情況2 假設pve 的管理口味eth0 openwrt中橋接的是eth0 eth1 eth2 那么電腦連接eth3或者pve管理口設置eth3&#xf…

【C#】設置有線網卡IP地址,子網掩碼,網關,DNS

方法 public partial class ComputerInfo{/// <summary>/// 設置IP地址&#xff0c;子網掩碼&#xff0c;網關&#xff0c;DNS/// </summary>public static List<NetworkAdapterInfo> SetIpAddressSubMaskDnsGeteway(string ipAddress, string subMask, stri…

MySQL庫的操作

文章目錄 MySQL庫的操作1. 創建數據庫2. 字符集和校驗規則(1) 查看系統默認字符集以及校驗規則(2) 查看數據庫支持的字符集和校驗規則(3) 案例(4) 校驗規則對數據庫的影響 3. 查看數據庫4. 修改數據庫5. 刪除數據庫6. 數據庫的備份和恢復(1) 備份(2) 還原 7. 查看連接情況 MySQ…

在 Windows 中恢復數據的 5 種方法

發生數據丟失的原因有多種。無論是因為文件被意外刪除、文件系統或操作系統損壞&#xff0c;還是由于軟件或硬件級別的存儲故障&#xff0c;數據都會在您最意想不到的時候丟失。今天我們重點介紹五種數據恢復方法&#xff0c;以應對意外情況的發生。 1.從另一臺機器啟動硬盤 如…

分享一組天氣組件

先看效果&#xff1a; CSS部分代碼&#xff08;查看更多&#xff09;&#xff1a; <style>:root {--bg-color: #E9F5FA;--day-text-color: #4DB0D3;/* 多云 */--cloudy-background: #4DB0D3;--cloudy-temperature: #E6DF95;--cloudy-content: #D3EBF4;/* 晴 */--sunny-b…

python基礎環境建設(pip、anaconda)

1.pip 配置文件路徑&#xff1a; centos&#xff1a;~/.pip/pip.conf windows: C:\Users\admin\AppData\Roaming\pip\pip.ini 文件內容&#xff1a; [global] index-url http://IP/repository/pypi-tsinghua/simple trusted-hostIP今天centos7.9、python3.6環境 pip install…

Https、CA證書、數字簽名

Https Http協議 Http協議是目前應用比較多應用層協議&#xff0c;瀏覽器對于Http協議已經實現。Http協議基本的構成部分有 請求行 &#xff1a; 請求報文的第一行請求頭 &#xff1a; 從第二行開始為請求頭內容的開始部分。每一個請求頭都是由K-V鍵值對組成。請求體&#xf…

【C++入門到精通】C++入門 —— vector (STL)

閱讀導航 前言一、vector簡介1. 概念2. 特點 二、vector的使用1.vector 構造函數2. vector 空間增長問題?resize 和 reserve 函數 3. vector 增刪查改?operator[] 函數 三、迭代器失效溫馨提示 前言 前面我們講了C語言的基礎知識&#xff0c;也了解了一些數據結構&#xff0…

軟件測試基礎篇——Docker

1、docker技術概述 docker描述&#xff1a;docker是一項虛擬化的容器技術&#xff08;類似于虛擬機&#xff09;&#xff0c;docker技術給使用者提供一個平臺&#xff0c;在該平臺上可以利用提供的容器&#xff0c;對每一個應用程序進行單獨的封裝隔離&#xff0c;每一個應用程…

spring 2.7.14 cors 設置 allowedOrigins(“*“)通配符 失效怎么解決

失效代碼&#xff1a; package com.yukuanyan.searcher_web.config;import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.WebM…

計算機競賽 opencv python 深度學習垃圾圖像分類系統

0 前言 &#x1f525; 優質競賽項目系列&#xff0c;今天要分享的是 &#x1f6a9; opencv python 深度學習垃圾分類系統 &#x1f947;學長這里給一個題目綜合評分(每項滿分5分) 難度系數&#xff1a;3分工作量&#xff1a;3分創新點&#xff1a;4分 這是一個較為新穎的競…