【C++】Json-Rpc框架项目介绍(1)

news2025/4/24 4:36:47

项目介绍

RPC(Remote Procedure Call)即远程过程调用,是一种通过网络从远程计算机程序中请求服务而不需要了解底层网络实现细节的一种 协议
RPC(Remote Procedure Call)可以使用多种网络协议进行通信,如 HTTP 、TCP 、UDP等。就像调用本地方法一样调用远程方法。

RPC框架

  • 序列化协议
  • 通信协议
  • 连接复用
  • 服务注册
  • 服务发现
  • 服务订阅和通知
  • 负载均衡
  • 服务监控
  • 同步调用
  • 异步调用

技术选型

目前RPC的实现方案主要有两种:

    • client和server继承公共接口:
    • 根据IDL(接口描述语言)定义公共接口
    • 编写代码生成器根据 IDL 语言生成相关的C++、Java代码
    • 客户端和服务器向上继承公共接口
    • 缺点:使用Protobuf、json可以定义IDL接口,并生成RPC相关代码,其中Protobuf需要通过protoc生成强类型代码,灵活性受限,且对理解不友好,如果用Json定义IDL语言,需要自己编写代码生成器,难度较大,暂不考虑这种方案
  • 实现一个远程调用接口call,然后传入函数名参数来调用RPC接口,我们采用这种方案

  • 网络传输的参数和返回值映射到对应RPC接口上:
    使用JSON类型,设计好参数和返回值协议

  • 网络传输:
    使用muduo库来实现网络传输

  • 序列化和反序列化
    使用JSON来实现

开发环境LInux

  • Linux (Centos-7.6 / Ubuntu6.4)
  • Vscode / Vim
  • g++ / gdb
  • Makefile

Muduo库

muduo是是由陈硕大佬开发,是一个基于 非阻塞IO事件驱动 的C++高并发TCP网络编程库。它是一款基于主从Reactor模型的网络库,其使用的线程模型是 one loop per thread

  • 一个线程只能有一个事件循环,用于响应计时器和IO时间
  • 一个文件描述符只能由一个线程进行读写,也就是一个TCP连接必须归属于某个EventLoop

C++11异步操作

std::future

std::future是C++11标准库中的一个模版类,它表示一个 异步操作的结果 ,当我们在多线程编程中使用异步任务时,std::future可以帮助我们在需要的时候获取任务的执行结果。它的一个主要特性就是能够阻塞当前线程,直到异步操作完成,确保我们在获取结果时不会遇到未完成的操作。
应用场景:

  • 异步任务:当我们在后台执行一些耗时操作时,如网络请求和计算密集型任务等,std::future可以表示异步执行的结果。通过创建新线程执行任务,实现任务的并行处理,提高程序的效率
  • 并发控制:我们可以通过使用std::future是线程之间的同步,确保任务完成后再获取结果并继续执行后续操作
  • 结果获取:std::future提供了一种安全的方式来获取异步任务的结果,我们可以使用 std::future::get()函数来获取异步任务的执行结果,并且这个函数会阻塞当前线程,直到异步操作完成,确保后序操作在结果获取后执行,同时保证了线程之间的同步。

std::async

std::async 是一种将任务与 std::future 关联的方法,它创建并运行一个异步任务,并返回一个与任务关联的 future 对象。
其中 std::async 是否启动一个新线程,或者在等待 futrue 时,任务是否同步运行都取决于你给的参数 std::launch:

  • std::launch::deferred 表明该函数会被延迟调用,直到调用 get() 或者 wait() 才会开始执行任务
  • std::launch::async表示函数会在自己创建的线程上面运行
  • std::launch::deferred | std::launch::async 取决于系统内部的资源的自动决策,当高资源可用时,采用 std::launch::async ,创建新线程实现并发,相反,则采std::launch::deferred 策略,在调用线程上执行,避免资源竞争和崩溃风险。
示例代码
#include <iostream>
#include <future>
#include <chrono>

std::string async_task()
{
    std::cout << "任务执行中" << std::endl;
    return "获取成功";
}

int main()
{
    std::future<std::string> result = std::async(std::launch::deferred,async_task);
    std::this_thread::sleep_for(std::chrono::seconds(10));
    std::cout << "任务在等待10s后再执行" << std::endl;
    std::string name = result.get();
    std::cout << name << std::endl;
    
    return 0;
}

结果:

任务在等待10s后再执行
任务执行中
获取成功
std::string async_task()
{
    std::cout << "任务正在执行" << std::endl;
    return "获取成功";
}

int main()
{
    std::future<std::string> result = std::async(std::launch::async,async_task);
    std::this_thread::sleep_for(std::chrono::seconds(10));

    std::string name = result.get();
    std::cout << name << std::endl;
    
    return 0;
}

结果:

任务正在执行
获取成功

std::packaged_task

std::packaged_task就是将任务和 std::future 绑定在一起的模版,是一种对任务的封装,我们可以通过std::packaged_task对象获取任务相关联的std::future对象,通过调用 get_future() 方法获得。std::packaged_task的模版参数是函数签名。
可以把std::futurestd::async 看成是分开的,而std::packaged_task则是一个整体

示例代码
#include <iostream>
#include <future>
#include <thread>
#include <utility>

std::string async_task() 
{
    std::cout << "任务执行中" << std::endl;
    return "获取成功";
}

int main() 
{
    // 1. 创建 packaged_task 并获取 future
    std::packaged_task<std::string()> task(async_task);
    std::future<std::string> result = task.get_future();

    // 2. 将任务移动到新线程中异步执行
    std::thread t(std::move(task));
    t.detach();  // 或 t.join()

    // 3. 获取结果(阻塞直到任务完成)
    std::string name = result.get();  // 若任务未执行会在此阻塞
    std::cout << name << std::endl;

    return 0;
}


结果:

任务执行中
获取成功

std::promise

std::promise提供了一种设置值的方式,它可以在设置之后通过相关联的 std::futrue对象进行读取。其实就是之前std::futrue需要等待异步函数的返回值,但std::promise提供了一种手动方式让std::futrue就绪

示例代码
void task(std::promise<int> promise_result)
{
    int result = 2;
    std::cout << "task result: " << result << std::endl;
    std::this_thread::sleep_for(std::chrono::seconds(5));
    promise_result.set_value(result);
}

int main()
{
    std::promise<int> promise_result;
    std::future<int> future_result = promise_result.get_future();

    std::thread task_thread(task,std::move(promise_result));
    task_thread.detach();
    std::this_thread::sleep_for(std::chrono::seconds(1));
    std::cout << "执行其他操作" << std::endl;

    int result = future_result.get();
    std::cout << "result: " << result << std::endl;

    return 0;
}

结果:

task result: 2
执行其他操作
result: 2

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

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

相关文章

window上 elasticsearch v9.0 与 jmeter5.6.3版本 冲突,造成es 启动失败

[2025-04-22T11:00:22,508][ERROR][o.e.b.Elasticsearch ] [AIRUY] fatal exception while booting Elasticsearchjava.nio.file.NoSuchFileException: D:\Program Files\apache-jmeter-5.6.3\lib\logkit-2.0.jar 解决方案&#xff1a; 降低 es安装版本 &#xff0c;选择…

【C++初阶】第15课—模版进阶

文章目录 1. 模版参数2. 模版的特化2.1 概念2.2 函数模版特化2.3 类模板特化2.3.1 全特化2.3.2 偏特化 3. 模版的分离和编译4. 总结 1. 模版参数 模版参数分为类型形参和非类型参数之前我们写过的大量代码&#xff0c;都是用模版定义类的参数类型&#xff0c;跟在class和typena…

黑阈免激活版:智能管理后台,优化手机性能

在使用安卓手机的过程中&#xff0c;许多用户会遇到手机卡顿、电池续航不足等问题。这些问题通常是由于后台运行的应用程序过多&#xff0c;占用大量系统资源导致的。今天&#xff0c;我们要介绍的 黑阈免激活版&#xff0c;就是这样一款由南京简域网络科技工作室开发的手机辅助…

Mujoco robosuite 机器人模型

import ctypes import os# 获取当前脚本所在的目录 script_dir os.path.dirname(os.path.abspath(__file__))# 构建库文件的相对路径 lib_relative_path os.path.join(dynamic_models, UR5e, Jb.so)# 拼接成完整的路径 lib_path os.path.join(script_dir, lib_relative_path…

K8s:概念、特点、核心组件与简单应用

一、引言 在当今云计算和容器技术蓬勃发展的时代&#xff0c;Kubernetes&#xff08;简称 K8s&#xff09;已成为容器编排领域的事实标准。它为管理容器化应用提供了高效、可靠的解决方案&#xff0c;极大地简化了应用的部署、扩展和运维过程。无论是小型初创公司还是大型企业…

STM32的定时器输出PWM时,死区时间(DTR)如何计算

在 STM32F429&#xff08;以及所有 STM32F4 “高级定时器”&#xff09;中&#xff0c;死区时间由 TIMx_BDTR 寄存器的 8 位 “Dead‑Time Generator” 字段 DTG[7:0] 来配置。其计算分三步&#xff1a; 计算死区时钟周期 tDTS TIM1 时钟源为 APB2 定时器时钟&#xff08;PCL…

STC32G12K128单片机GPIO模式SPI操作NorFlash并实现FatFS文件系统

STC32G12K128单片机GPIO模式SPI操作NorFlash并实现FatFS文件系统 NorFlash简介NorFlash操作驱动代码文件系统测试代码 NorFlash简介 NOR Flash是一种类型的非易失性存储器&#xff0c;它允许在不移除电源的情况下保留数据。NOR Flash的名字来源于其内部结构中使用的NOR逻辑门。…

ClickHouse 设计与细节

1. 引言 ClickHouse 是一款备受欢迎的开源列式在线分析处理 (OLAP) 数据库管理系统&#xff0c;专为在海量数据集上实现高性能实时分析而设计&#xff0c;并具备极高的数据摄取速率 1。其在各种行业中得到了广泛应用&#xff0c;包括众多知名企业&#xff0c;例如超过半数的财…

智能体MCP 实现数据可视化分析

参考: 在线体验 https://www.doubao.com/chat/ 下载安装离线体验 WPS软件上的表格分析 云上创建 阿里mcp:https://developer.aliyun.com/article/1661198 (搜索加可视化) 案例 用cline 或者cherry studio实现 mcp server:excel-mcp-server、quickchart-mcp-server

再看开源多模态RAG的视觉文档(OCR-Free)检索增强生成方案-VDocRAG

前期几个工作提到&#xff0c;基于OCR的文档解析RAG的方式进行知识库问答&#xff0c;受限文档结构复杂多样&#xff0c;各个环节的解析泛化能力较差&#xff0c;无法完美的对文档进行解析。因此出现了一些基于多模态大模型的RAG方案。如下&#xff1a; 【RAG&多模态】多模…

深入浅出 NVIDIA CUDA 架构与并行计算技术

&#x1f407;明明跟你说过&#xff1a;个人主页 &#x1f3c5;个人专栏&#xff1a;《深度探秘&#xff1a;AI界的007》 &#x1f3c5; &#x1f516;行路有良友&#xff0c;便是天堂&#x1f516; 目录 一、引言 1、CUDA为何重要&#xff1a;并行计算的时代 2、NVIDIA在…

FPGA系列之DDS信号发生器设计(DE2-115开发板)

一、IP核 IP(Intellectual Property)原指知识产权、著作权等&#xff0c;在IC设计领域通常被理解为实现某种功能的设计。IP模块则是完成某种比较复杂算法或功能&#xff08;如FIR滤波器、FFT、SDRAM控制器、PCIe接口、CPU核等&#xff09;并且参数可修改的电路模块&#xff0c…

【Dv3Admin】从零搭建Git项目安装·配置·初始化

项目采用 Django 与 Vue3 技术栈构建&#xff0c;具备强大的后端扩展能力与现代前端交互体验。完整实现了权限管理、任务队列、WebSocket 通信、系统配置等功能&#xff0c;适用于构建中后台管理系统与多租户平台。 本文章内容涵盖环境搭建、虚拟环境配置、前后端部署、项目结…

P3416-图论-法1.BFS / 法2.Floyd

这道题虽然标签有floyd但是直接bfs也能过 其实事实证明还是bfs快&#xff0c;因为bfs只需要遍历特定的点&#xff0c;但是floyd需要考虑遍历所有可能的中介点 法1.BFS 用字典存储每个点所能普及的范围&#xff0c;然后用对每个点bfs进行拓展 nint(input())temp[]#xmax0;yma…

极狐GitLab 议题和史诗创建的速率限制如何设置?

极狐GitLab 是 GitLab 在中国的发行版&#xff0c;关于中文参考文档和资料有&#xff1a; 极狐GitLab 中文文档极狐GitLab 中文论坛极狐GitLab 官网 议题和史诗创建的速率限制 (BASIC SELF) 速率限制是为了控制新史诗和议题的创建速度。例如&#xff0c;如果您将限制设置为 …

提交到Gitee仓库

文章目录 注册配置公钥创建空白的码云仓库把本地项目上传到码云对应的空白仓库中 注册 注册并激活码云账号&#xff08; 注册页面地址&#xff1a;https://gitee.com/signup &#xff09; 可以在自己C盘/用户/用户名/.ssh 可以看到 有id_rsa.pub 以前在GitHub注册时搞过&…

oracle中错误总结

oracle中给表起别名不能用as&#xff0c;用as报错 在 Oracle 数据库中&#xff0c;​​WITH 子句&#xff08;即 CTE&#xff0c;公共表表达式&#xff09;允许后续定义的子查询引用前面已经定义的 CTE​​&#xff0c;但 ​​前面的 CTE 无法引用后面的 CTE​​。这种设计类似…

纽约大学具身智能体在城市空间中的视觉导航之旅!CityWalker:从海量网络视频中学习城市导航

作者&#xff1a;Xinhao Liu, Jintong Li, Yicheng Jiang, Niranjan Sujay, Zhicheng Yang, Juexiao Zhang, John Abanes, Jing Zhang, Chen Feng单位&#xff1a;纽约大学论文标题&#xff1a;CityWalker: Learning Embodied Urban Navigation from Web-Scale Videos论文链接&…

OpenCV颜色变换cvtColor

OpenCV计算机视觉开发实践&#xff1a;基于Qt C - 商品搜索 - 京东 颜色变换是imgproc模块中一个常用的功能。我们生活中看到的大多数彩色图片都是RGB类型的&#xff0c;但是在进行图像处理时需要用到灰度图、二值图、HSV&#xff08;六角锥体模型&#xff0c;这个模型中颜色的…

Manus技术架构、实现内幕及分布式智能体项目实战

Manus技术架构、实现内幕及分布式智能体项目实战 模块一&#xff1a; 剖析Manus分布式多智能体全生命周期、九大核心模块及MCP协议&#xff0c;构建低幻觉、高效且具备动态失败处理能力的Manus系统。 模块二&#xff1a; 解析Manus大模型Agent操作电脑的原理与关键API&#xf…