当前位置: 首页 > wzjs >正文

深圳高端网站建设网页设计seo网站推广与优化方案

深圳高端网站建设网页设计,seo网站推广与优化方案,跨境电商平台app排名,找个做游戏的视频网站好🚀 [协程与异步服务器实战]:[C20协程原理与Boost.Asio异步服务器开发] 📅 更新时间:2025年07月05日 🏷️ 标签:C20 | 协程 | Boost.Asio | 异步编程 | 网络服务器 文章目录 前言一、什么是协程?…

🚀 [协程与异步服务器实战]:[C++20协程原理与Boost.Asio异步服务器开发]
📅 更新时间:2025年07月05日
🏷️ 标签:C++20 | 协程 | Boost.Asio | 异步编程 | 网络服务器

文章目录

  • 前言
  • 一、什么是协程?
  • 二、线程与协程?
  • 三、使用协程搭建异步服务器进行通信
    • 1.服务端
      • 1.流程图
      • 2.服务端代码
        • 1.主函数入口
        • 2.lisenter 协程函数
        • 3.echo协程函数
    • 2.客户端
  • 四、测试
  • 总结


前言

今天我们学习协程的基本概念,以及如何用协程来搭建一个简单的异步服务器来进行与客户端的收发数据


一、什么是协程?

协程(Coroutine)是一种比线程更轻量级的“并发编程”方式
它允许你在一个线程内,把任务分成多个可以挂起和恢复的小段,写出“像同步一样的异步代码”。

协程的特点
可以在执行过程中主动暂停(挂起),等条件满足后恢复执行
多个协程可以在同一个线程内切换,切换速度非常快
由程序员或框架调度,而不是操作系统

总结
协程就是可以随时挂起和恢复的轻量级任务,让你用很少的资源实现高效的并发和异步编程

二、线程与协程?

直观比喻
线程像“多个人各自做事”
协程像“一个人做多件事,可以随时暂停当前任务,去做别的,再回来继续”

三、使用协程搭建异步服务器进行通信

1.服务端

1.流程图

在这里插入图片描述

1.程序启动(main)
初始化 io_context
设置信号处理(监听 Ctrl+C 等信号,优雅退出)
启动 lisenter 协程

2.lisenter 协程
创建 acceptor,监听 10086 端口
进入无限循环:
异步等待新连接(co_await acceptor.async_accept()
每有一个新连接,启动一个 echo 协程处理该连接

3.echo 协程
进入无限循环:
异步读取客户端数据(co_await socket.async_read_some()
异步写回数据(co_await async_write()
信号处理
收到终止信号时,调用 ioc.stop(),优雅关闭服务器

2.服务端代码

1.主函数入口

我们在主函数中利用 try catch 来进行跑代码,这样可以防止后续的出错,
我们先定义一个信号集signal_set来实现服务器的优雅退出,当客户端使用Ctrl+C等操作的时候,我们可以通知 上下文 io_context直接调用 .stop() 来暂停服务

int main()
{try{boost::asio::io_context ioc(1);boost::asio::signal_set signals(ioc, SIGINT, SIGTERM);signals.async_wait([&](auto,auto){ioc.stop();});co_spawn(ioc,lisenter(),detached);//启动协程ioc.run();}catch(std::exception& e){std::cout << "main Exception is" << e.what() << std::endl;}
}

在写 Lambda 表达式的时候如果要调用上下文io_context必须用&捕获
核心原因是:io_context(以及很多 Asio 相关对象)本身禁止拷贝,只能被引用捕获,不能被值捕获

co_spawn(ioc,lisenter(),detached);//启动协程

co_spawn
co_spawn表示启动一个协程,参数分别为调度器执行的函数,以及启动方式, 比如我们启动了一个协程,deatched表示将协程对象分离出来,这种启动方式可以启动多个协程,他们都是独立的,如何调度取决于调度器,在用户的感知上更像是线程调度的模式,类似于并发运行,其实底层都是串行的

此时需要传入三个参数
第一个参数
boost::asio::io_context
所有异步事件和协程都要绑定到某个 io_context,它负责调度和执行

第二个参数
是你自定义的协程函数,返回类型通常是 awaitable<void>
这里我们自定义的函数是lisenter()

第三个参数
协程的完成方式
总共有三种,分别是
detached
作用:协程分离运行,主程序不关心协程的返回值和异常。
用法:适合“只管启动,不关心后续”的场景(如服务器监听、后台任务)

use_awaitable
作用:让协程的结果可以被 co_await 等待,用于协程之间的嵌套和组合。
用法:适合你想在另一个协程里等待这个协程的结果

最后一种是自定义的回调函数

所以我们这句话

co_spawn(ioc,lisenter(),detached);//启动协程

的完整意思就是
在 ioc 这个事件循环中,启动一个 lisenter 协程,让它自己运行,主程序不关心它的结果

2.lisenter 协程函数

我们定义一个协程函数,然后在协程函数中我们创建一个监听器acceptor进行绑定上下文tcp协议端口号

然后我们调用一个死循环,内部异步的进行监听然后创建一个socket,然后我们根据这个socket再创建一个协程echo单独管理此客户端的通信

awaitable<void> lisenter()
{auto executor = co_await this_coro::executor;//co_await异步获取调度器tcp::acceptor acceptor(executor, { tcp::v4(),10086 });for (;;){tcp::socket socket = co_await acceptor.async_accept(use_awaitable);co_spawn(executor, echo(std::move(socket)), detached);//为每一个连接单独启动 一个协程进行收发数据}
}

如果要写协程函数,必须是这种类型

awaitable<T>

我们在协程中进行了对当前协程获取调度器的实现

auto executor = co_await this_coro::executor;//co_await异步获取调度器

Boost.Asio 中,executor 是一个“执行环境”,负责调度和管理异步操作的执行
常见的 executorio_context::executor_type,它和 io_context 绑定

因为我们在主函数中使用了

co_spawn(ioc, lisenter(), detached)

启动协程时,协程会自动和 ioc 绑定
但在协程体内,如果你要创建新的异步对象(如 acceptor),需要明确告诉它用哪个 executor,否则它不知道该和哪个事件循环关联
所以相当于给这个监听器绑定了一个上下文io_context

然后我们再来介绍一下
co_await
co_awaitC++20 协程的通用关键字,它的作用是等待一个 “可等待对象” 完成,并获取其结果

比如这里我们用来获取当前协程的调度器和监听器分配的socket

auto executor = co_await this_coro::executor;
tcp::socket socket = co_await acceptor.async_accept(use_awaitable);
3.echo协程函数

这个协程函数就是单独为当前分配的客户端进行读写通信的实现

awaitable<void>echo(tcp::socket socket)
{try{char data[1024];for (;;){std::size_t n=co_await socket.async_read_some(boost::asio::buffer(data), use_awaitable);co_await async_write(socket, boost::asio::buffer(data, n), use_awaitable);}}catch (std::exception& e){std::cout << "echo Exception is" << e.what() << std::endl;}
}

我们多次利用这个co_await实现了将看似同步的代码,实现了异步等待的操作,比如这句

//获取收到数据长度
std::size_t n=co_await 
socket.async_read_some(boost::asio::buffer(data), use_awaitable);//异步写
co_await async_write
(socket, boost::asio::buffer(data, n), use_awaitable);

2.客户端

客户端我们还是用以前的简易的版本,发送 hello world 进行测试,不考虑其他的问题

#include <iostream>
#include<boost/asio.hpp>using namespace std;
using namespace boost::asio::ip;
const int MAX_LENGTH = 1024;int main()
{try{boost::asio::io_context ioc;tcp::endpoint remote_ep(boost::asio::ip::make_address("127.0.0.1"), 10086);tcp::socket sock(ioc);boost::system::error_code error = boost::asio::error::host_not_found;sock.connect(remote_ep, error);if (error){cout << "connect failed, code is" << error.value() <<"  error msg is "<<error.what() << endl;return 0;}cout << "Enter Message:" << endl;char request[MAX_LENGTH];cin.getline(request, MAX_LENGTH);size_t request_len = strlen(request);boost::asio::write(sock, boost::asio::buffer(request, request_len));char reply[MAX_LENGTH];size_t reply_len = boost::asio::read(sock, boost::asio::buffer(reply, request_len));cout << "reply is" << string(reply,reply_len) << endl;getchar();}catch (std::exception& e){std::cout << "main exception is " << e.what() << std::endl;}return 0;
}

四、测试

客户端成功与服务器进行通信
在这里插入图片描述

总结

学习了协程了相关概念,以及如何利用协程来搭建一个简易的异步服务器的小demo

http://www.dtcms.com/wzjs/491712.html

相关文章:

  • 网站建设必须要其他后台吗seo网站排名优化工具
  • 商城网站平台怎么做竞价推广托管服务
  • wordpress 订阅google seo是什么啊
  • 网站后台 js框架湘潭网站设计外包服务
  • 怎么建网站链接网络广告电话
  • 怎么建设一个自己的电商网站淮北seo
  • 图书建设网站国外搜索引擎网站
  • 太原网站建设案例搜狗站长
  • 公司需要做网站吗seo网站关键词排名优化公司
  • 网站开发用工工程师百度信息流推广教程
  • 新冠为什么莫名消失了乐陵seo优化
  • 福建网站开发速成班怎么推广引流客户
  • 临沂在线上网站建设友缘在线官网
  • 服装网站目标榜单优化
  • 坡头网站建设公司专业做网站的公司
  • 做网站一定要有公司吗象山关键词seo排名
  • 最好的网站建设公司有哪些怎样做引流推广
  • 传奇私服网站做ssl网站排名软件优化
  • 新手如何制作网站怎么自己做一个网页
  • 保定模板做网站百度推广怎么操作流程
  • 企业门户网站在信息系统架构中属于哪个层次b站推广引流最佳方法
  • 做网站都有什么成本公司域名查询官网
  • 网站建设面临的困难销售的技巧与口才
  • 怎样做app网站建设全国各城市疫情高峰感染高峰进度
  • 佛山从事网站建设seo管理平台
  • 浏览器网站网址大全广州抖音推广公司
  • 网站建设的活怎么接seo排名优化软件有
  • 日本设计类网站seowhy官网
  • 网站banner图设计成多少合适优化资讯
  • 腾云公司做网站bt磁力天堂torrentkitty