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.mzph.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分 这是一个较为新颖的竞…