【C++boost::asio网络编程】使用asio协程搭建异步echo服务器的笔记

【C++boost::asio网络编程】使用asio协程搭建异步服务器的笔记

  • 协程和线程关系以及线程和进程的关系简单区分
    • 资源消耗与开销
    • 调度与上下文切换
    • 并发性
    • 独立性
  • main函数
  • listener函数
  • echo函数

协程和线程关系以及线程和进程的关系简单区分

资源消耗与开销

  • 进程与线程:
    • 进程 是操作系统分配资源的基本单位,每个进程拥有自己的内存空间、文件描述符等资源。
    • 线程 是进程中的执行单元,同一个进程中的多个线程共享进程的资源(如内存空间、文件描述符等)。线程的创建和上下文切换相对于进程来说,开销较小,但仍然需要操作系统的支持。
  • 协程与线程:
    • 协程 是一种轻量级的用户级执行单元,它与线程相比,具有更小的资源开销。多个协程通常运行在一个线程中,共享线程的资源(如 CPU 时间、内存等)。
    • 线程 是操作系统调度的基本单元,协程是在用户级别进行调度的,它并不依赖操作系统进行上下文切换。因此,协程的切换和调度开销比线程小得多。

调度与上下文切换

  • 进程与线程:
    • 进程线程 的调度通常由操作系统管理,线程的上下文切换涉及到保存和恢复 CPU 寄存器、内存映射等状态。
    • 线程切换 的开销比进程切换小,但仍然需要操作系统的干预。
  • 协程与线程:
    • 协程 的调度通常是由程序自身管理的,协程的上下文切换不需要操作系统的参与,通常只是通过保存和恢复少量的状态(例如局部变量、程序计数器等)来完成。因此,协程的上下文切换比线程切换的开销更小。

并发性

  • 进程与线程:
    • 进程 之间是完全独立的,一个进程的崩溃不会直接影响到其他进程。
    • 线程 之间是并发的,在同一进程中可以并行执行多个线程(在多核 CPU 上,多个线程可以真正地并行运行),但是它们会共享进程的资源。
  • 协程与线程:
    • 协程 是轻量级的并发单元,它们运行在单个线程中。多个协程可以在同一个线程中并发执行,但它们并不会并行执行(即不会在多个 CPU 核心上同时运行)。协程通过协作式调度来实现并发,通常在 I/O 操作或者其他需要等待的地方挂起,给其他协程执行的机会。

独立性

  • 进程与线程:
    • 进程 是独立的,通常不会直接共享内存等资源,进程间的通信需要通过特定的机制(如管道、消息队列、共享内存等)。
    • 线程 共享进程的内存空间,可以直接访问共享数据,因此线程之间的通信较为方便,但也需要注意同步问题。
  • 协程与线程:
    • 协程 不独立,它们共享同一个线程的资源。多个协程之间的切换不会涉及到线程的上下文切换,只是在协程之间的切换。协程之间通常通过共享内存来通信,但也需要小心避免并发问题。

main函数

int main()
{try{boost::asio::io_context ioc;boost::asio::signal_set signals(ioc, SIGINT, SIGTERM);signals.async_wait([&](auto, auto) {ioc.stop();});boost::asio::co_spawn(ioc, listener, boost::asio::detached);ioc.run();}catch (const std::exception& e){std::cout << e.what() << std::endl;}return 0;
}
boost::asio::co_spawn(ioc, listener, boost::asio::detached);

  这段代码的主要功能是启动一个新的协程来运行listener函数(这个函数用来监听来自客户端的连接),

listener函数

boost::asio::awaitable<void> listener()
{auto executor = co_await boost::asio::this_coro::executor;boost::asio::ip::tcp::acceptor acceptor(executor, { boost::asio::ip::tcp::v4(),8888 });while (true){boost::asio::ip::tcp::socket socket = co_await acceptor.async_accept(boost::asio::use_awaitable);boost::asio::co_spawn(executor, echo(std::move(socket)), boost::asio::detached);}
}
boost::asio::awaitable<void> listener()

  首先来介绍一下这个返回值为什么要这么写:boost::asio::awaitable<T>是一种协程返回类型,表示该函数返回的是一个可以挂起的协程
什么叫做返回一个可以挂起的协程?
  这个意思就是说该函数返回的对象能在某个点暂停执行,等待某个操作(例如异步IO,网络请求等)完成后再继续执行,这种特性是现代协程模型中的核心概念。在C++20中,协程通过co_await,co_return等关键字来实现,例如co_await用于挂起当前协程并等待一个异步操作完成。
  而挂起指的是协程在执行过程中暂停下来,等待某些条件或操作完成,这时,协程将不会占用CPU,其他任务可以继续执行,直到挂起的操作完成之后,该协程才会恢复执行

auto executor = co_await boost::asio::this_coro::executor;

  这段代码就是用来获取当前协程所在的"执行上下文"。在Boost::asio中,executor是一个对象,主要负责调度和执行任务,它是io_context或io_service的一部分,确保异步任务能够执行。
  co_await是一个协程操作符,它用户挂起当前协程,直到等待的对象完成.通过co_wait,协程不会立即返回,而是将控制权交还给调用者,直到获取到执行器对象为止。

boost::asio::ip::tcp::socket socket = co_await acceptor.async_accept(boost::asio::use_awaitable);

  async_accept中的参数boost::asio::use_awaitable的主要作用是使得async_accept能够与C++20的协程机制兼容,在这段代码中,它使得async_accept返回的是一个C++20 协程机制交互的“协程兼容对象“,能够在异步操作完成时继续执行

boost::asio::co_spawn(executor, echo(std::move(socket)), boost::asio::detached);

  这行代码的意思是启动一个协程。第一个参数是一个执行器对象,用户控制协程的上下文。第二个参数是socket对象,表示创建的协程通过这个对象为客户端进行服务,第三个参数的作用是表示不需要关心启动的这个协程完成的情况。

echo函数

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

  echo函数的作用就是接收客户端发过来的信息然后转发回去,实现一个简单的echo server服务器。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/892570.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【NLP】语言模型的发展历程 (1)

语言模型的发展历程系列博客主要包含以下文章&#xff1a; 【NLP】语言模型的发展历程 (1)【NLP】大语言模型的发展历程 (2) 本篇博客是该系列的第一篇&#xff0c;主要讲讲 语言模型&#xff08;LM&#xff0c;Language Model&#xff09; 的发展历程。 文章目录 一、统计语…

JNI使用类签名及字段签名获取字段值

1.获取逻辑: 2.获取逻辑实现代码: extern "C" JNIEXPORT void JNICALL Java_com_example_jnibasetypedemo_MainActivity_getAnimalsNameFromJNI(JNIEnv *env, jobject thiz,jobjectArray animals) {jobject animalObj;int len env->GetArrayLength(animals);//获…

Vue 封装公告滚动

文章目录 需求分析1. 创建公告组件Notice.vue2. 注册全局组件3. 使用 需求 系统中需要有一个公告展示&#xff0c;且这个公告位于页面上方&#xff0c;每个页面都要看到 分析 1. 创建公告组件Notice.vue 第一种 在你的项目的合适组件目录下&#xff08;比如components目录&a…

Win10微调大语言模型ChatGLM2-6B

在《Win10本地部署大语言模型ChatGLM2-6B-CSDN博客》基础上进行&#xff0c;官方文档在这里&#xff0c;参考了这篇文章 首先确保ChatGLM2-6B下的有ptuning AdvertiseGen下载地址1&#xff0c;地址2&#xff0c;文件中数据留几行 模型文件下载地址 &#xff08;注意&#xff1…

HTTP-响应协议

HTTP的响应过程&#xff1f; 浏览器请求数据--》web服务器过程&#xff1a;请求过程 web服务器将响应数据-》到浏览器&#xff1a;响应过程 响应数据有哪些内容&#xff1f; 1.和请求数据类似。 2. 响应体中存储着web服务器返回给浏览器的响应数据。并且注意响应头和响应体之间…

爬虫基础之爬取歌曲宝歌曲批量下载

声明&#xff1a;本案列仅供学习交流使用 任何用于非法用途均与本作者无关 需求分析: 网站:邓紫棋-mp3在线免费下载-歌曲宝-找歌就用歌曲宝-MP3音乐高品质在线免费下载 (gequbao.com) 爬取 歌曲名 歌曲 实现歌手名称下载所有歌曲 本案列所使用的模块 requests (发送…

C++ 鼠标轨迹算法 - 防止游戏检测

一.简介 鼠标轨迹算法是一种模拟人类鼠标操作的程序&#xff0c;它能够模拟出自然而真实的鼠标移动路径。 鼠标轨迹算法的底层实现采用C/C语言&#xff0c;原因在于C/C提供了高性能的执行能力和直接访问操作系统底层资源的能力。 鼠标轨迹算法具有以下优势&#xff1a; 模拟…

2025年中科院分区大类划分公布!新增8155本

2025年中科院分区表变更情况 扩大收录范围 2025年的期刊分区表在原有的自然科学&#xff08;SCIE&#xff09;、社会科学&#xff08;SSCI&#xff09;和人文科学&#xff08;AHCI&#xff09;的基础上&#xff0c;增加了ESCI期刊的收录&#xff0c;并根据这些期刊的数据进行…

【前端动效】HTML + CSS 实现打字机效果

目录 1. 效果展示 2. 思路分析 2.1 难点 2.2 实现思路 3. 代码实现 3.1 html部分 3.2 css部分 3.3 完整代码 4. 总结 1. 效果展示 如图所示&#xff0c;这次带来的是一个有趣的“擦除”效果&#xff0c;也可以叫做打字机效果&#xff0c;其中一段文本从左到右逐渐从…

提升租赁效率的租赁小程序全解析

内容概要 在如今快节奏的生活中&#xff0c;租赁小程序俨然成为了提升租赁效率的一把利器。无论是个人还是企业&#xff0c;都会因其便捷的功能而受益。简单来说&#xff0c;租赁小程序能让繁琐的租赁流程变得轻松、高效。在这里&#xff0c;我们将带您畅游租赁小程序的海洋&a…

Docker--Docker Compose(容器编排)

什么是 Docker Compose Docker Compose是Docker官方的开源项目&#xff0c;是一个用于定义和运行多容器Docker应用程序的工具。 服务&#xff08;Service&#xff09;&#xff1a;在Docker Compose中&#xff0c;一个服务实际上可以包括若干运行相同镜像的容器实例&#xff0…

搭建docker私有化仓库Harbor

Docker私有仓库概述 Docker私有仓库介绍 Docker私有仓库是个人、组织或企业内部用于存储和管理Docker镜像的存储库。Docker默认会有一个公共的仓库Docker Hub,而与Docker Hub不同,私有仓库是受限访问的,只有授权用户才能够上传、下载和管理其中的镜像。这种私有仓库可以部…

本地视频进度加入笔记+根据进度快速锁定视频位置

本地视频进度记录快速回溯 引言 在学习的过程中, 如果我们想快速记录当前看视频的位置, 后续回溯查找就会非常方便了。 实现效果 进度记录 通过按下快捷键ctrlaltu&#xff0c; 快速记录当前视频的进度信息,然后复制到typora软件内 快速回溯 在typora软件内, 选中视频索引…

网络传输层TCP协议

传输层TCP协议 1. TCP协议介绍 TCP&#xff08;Transmission Control Protocol&#xff0c;传输控制协议&#xff09;是一个要对数据的传输进行详细控制的传输层协议。 TCP 与 UDP 的不同&#xff0c;在于TCP是有连接、可靠、面向字节流的。具体来说&#xff0c;TCP设置了一大…

《自动驾驶与机器人中的SLAM技术》ch7:基于 ESKF 的松耦合 LIO 系统

目录 基于 ESKF 的松耦合 LIO 系统 1 坐标系说明 2 松耦合 LIO 系统的运动和观测方程 3 松耦合 LIO 系统的数据准备 3.1 CloudConvert 类 3.2 MessageSync 类 4 松耦合 LIO 系统的主要流程 4.1 IMU 静止初始化 4.2 ESKF 之 运动过程——使用 IMU 预测 4.3 使用 IMU 预测位姿进…

基于大语言模型的组合优化

摘要&#xff1a;组合优化&#xff08;Combinatorial Optimization, CO&#xff09;对于提高工程应用的效率和性能至关重要。随着问题规模的增大和依赖关系的复杂化&#xff0c;找到最优解变得极具挑战性。在处理现实世界的工程问题时&#xff0c;基于纯数学推理的算法存在局限…

【数据库】Unity 使用 Sqlite 数据库

1.找到需要三个 DLL Mono.Data.Sqlite.dllSystem.Data.dllsqlite3.dll 上面两个dll可在本地unity安装目录找到&#xff1a; C:\Program Files\Unity\Hub\Editor\2022.3.xxf1c1\Editor\Data\MonoBleedingEdge\lib\mono\unityjit-win32 下面dll可在sqlite官网下载到&#xff…

冒泡排序基础与实现

目录 1. 原理图 ​编辑 2. 什么是冒泡排序 3. 工作原理 3.1 具体步骤 3.2 时间复杂度 3.3 空间复杂度 4. 代码实现 5. 总结 1. 原理图 2. 什么是冒泡排序 冒泡排序&#xff08;Bubble Sort&#xff09;是一种简单的排序算法&#xff0c;它通过重复地遍历要排序的列表&am…

忘记了PDF文件的密码,怎么办?

PDF文件可以加密&#xff0c;大家都不陌生&#xff0c;并且大家应该也都知道PDF文件有两种密码&#xff0c;一个打开密码、一个限制编辑密码&#xff0c;因为PDF文件设置了密码&#xff0c;那么打开、编辑PDF文件就会受到限制。忘记了PDF密码该如何解密&#xff1f; PDF和offi…

【论文笔记】Sign Language Video Retrieval with Free-Form Textual Queries

&#x1f34e;个人主页&#xff1a;小嗷犬的个人主页 &#x1f34a;个人网站&#xff1a;小嗷犬的技术小站 &#x1f96d;个人信条&#xff1a;为天地立心&#xff0c;为生民立命&#xff0c;为往圣继绝学&#xff0c;为万世开太平。 基本信息 标题: Sign Language Video Retr…