全网唯一基于共享内存的C++ RPC框架

首先声明:我不是标题党,我是在找遍全网,没有找到一个基于共享内存实现、开源且跨平台的C++ RPC框架之后,才着手开发的这个框架。

项目地址:https://github.com/winsoft666/veigar


1. Veigar

Veigar一词来源于英雄联盟里面的“邪恶小法师-维迦”。

Veigar是一个跨平台的远程过程调用(RPC)框架,目前支持Windows、Linux平台。

Veigar基于共享内存技术实现,只支持本机进程或线程间的远程过程调用,这是Veigar与其他RPC框架(如Thrift、grpc)的最大不同之处。

2. 优势

与其他RPC框架相比,Veigar的优势在于:

  • 可以将任何函数暴露给调用方(不限语言,只要实现msgpack-rpc即可)。

  • 任何语言编写的程序都可以调用被暴露的函数。

  • 不需要学习IDL语言。

  • 不需要添加额外的代码生成步骤,仅需要C++代码。

  • 没有服务端和客户端的概念,每个Veigar实例间都可以相互调用。

  • 没有网络问题,如端口占用、半关闭状态等。

  • 没有诡异的端口假可用性问题(特别是在Windows系统上)。

3. 编译

虽然Veigar的底层是基于msgpack实现的,但已经将其包含到项目中,不需要额外编译和安装msgpack

虽然在veigar公共头文件引用了msgpack头文件,但这不会污染您的全局msgpack命名空间,因为Veigar中的msgpack命令空间为veigar_msgpack

Veigar仅支持编译为静态库。

可以使用CMake进行编译构建,也可以使用vcpkg进行安装,如:

vcpkg install veigar

4. 快速上手

在使用Veigar时,仅需要在项目中包含include目录,并链接静态库即可。

4.1 同步调用

下面是一个同步调用的示例:

本示例为了使代码更加简洁,没有对函数返回值进行校验,请在实际使用中不要这样做!

#include <iostream>
#include "veigar/veigar.h"int main(int argc, char** argv) {if (argc != 3) {return 1;}std::string channelName = argv[1];std::string targetChannelName = argv[2];veigar::Veigar vg;vg.bind("echo", [](const std::string& msg, int i, double d, std::vector<uint8_t> buf) {std::string result;// ...return result;});vg.init(channelName);std::vector<uint8_t> buf;veigar::CallResult ret = vg.syncCall(targetChannelName, 100, "echo", "hello", 12, 3.14, buf);if (ret.isSuccess()) {std::cout << ret.obj.get().as<std::string>() << std::endl;}else {std::cout << ret.errorMessage << std::endl;}vg.uninit();return 0;
}

每个Veigar实例有一个在本机范围内唯一的通道名称(Channel),在调用init函数时需要为Veigar指定通道名称,Veigar不会检测通道的唯一性,需要由调用者来保证通道名称的唯一性。

在上述示例中,需要通过命令行参数指定当前实例的通道名称和目标实例的通道名称,如:

sample.exe myself other

每个实例都绑定了名为echo的函数,该函数简单的原样返回msg参数字符串。

通过为syncCall函数指定“目标通道名称”、“函数名称”、“函数参数”及“超时毫秒数”就可以同步调用目标函数并得到调用结果。

4.2 拒绝异常

我不喜欢异常,因此Veigar也不会通过异常的形式来抛出错误,Veigar会主动捕获所有C++标准库、msgpack、boost异常,以返回值的形式返回给调用者。当调用失败时(!ret.isSuccess()),errorMessage中存储的错误信息就可能是Veigar捕获的异常信息。

4.3 异步调用

使用asyncCall函数可以实现异步调用。

下面是异步调用示例:

//
// 与同步调用相同
// ...
std::vector<uint8_t> buf;
std::shared_ptr<veigar::AsyncCallResult> acr = vg.asyncCall(targetChannelName, "echo", "hello", 12, 3.14, buf);
if (acr->second.valid()) {auto waitResult = acr->second.wait_for(std::chrono::milliseconds(100));if (waitResult == std::future_status::timeout) {// timeout}else {veigar::CallResult ret = std::move(acr->second.get());if(ret.isSuccess()) {std::cout << ret.obj.get().as<std::string>() << std::endl;}else {std::cout << ret.errorMessage << std::endl;}}
}vg.releaseCall(acr->first);//
// 与同步调用相同
// ...

与同步调用不同,asyncCall函数返回的是std::shared_ptr<veigar::AsyncCallResult>,而且调用者在获取到CallResult或不再关系调用结果时,需要调用releaseCall函数释放资源。

5. 性能

使用examples\echo程序作为测试用例。

启动A、B、C三个Channel,每个Channel分别使用2个线程向彼此调用100万次,如下图所示:
请添加图片描述

Windows平台测试结果

测试机器CPU配置:

12th Gen Intel(R) Core(TM) i7-12700H   2.30 GHz

测试结果如下:

Target channel names (Split by comma):
A,B,C
Async method(0/1):
0
Thread number for each target:
2
Call times each of thread:
1000000
Read/Write Timeout(ms):
100
[Thread 1, Target A] Calling...
[Thread 0, Target C] Calling...
[Thread 0, Target A] Calling...
[Thread 1, Target B] Calling...
[Thread 0, Target B] Calling...
[Thread 1, Target C] Calling...
[Thread 1, Target B] Total 1000000, Success 1000000, Error 0, Used: 59092341us, Average: 59us/call, 16922call/s.[Thread 0, Target B] Total 1000000, Success 1000000, Error 0, Used: 59112785us, Average: 59us/call, 16916call/s.[Thread 1, Target A] Total 1000000, Success 1000000, Error 0, Used: 59111520us, Average: 59us/call, 16917call/s.[Thread 0, Target C] Total 1000000, Success 1000000, Error 0, Used: 59126879us, Average: 59us/call, 16912call/s.[Thread 0, Target A] Total 1000000, Success 1000000, Error 0, Used: 59206766us, Average: 59us/call, 16889call/s.[Thread 1, Target C] Total 1000000, Success 1000000, Error 0, Used: 59299407us, Average: 59us/call, 16863call/s.

平均每次调用花费59微妙,每秒可以调用约16900次。

请添加图片描述

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

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

相关文章

彩虹全新 SUP 模板,卡卡云模板修复版

彩虹全新 SUP 模板&#xff0c;卡卡云模板&#xff0c;首页美化&#xff0c;登陆页美化&#xff0c;修复了 PC 端购物车页面显示不正常的问题。下载地址&#xff1a;彩虹全新 SUP 模板.zip 模板截图

vscode 设置打开中断的默认工作目录/路径

vscode 设置打开终端的默认工作目录/路径** 文章目录 vscode 设置打开终端的默认工作目录/路径**打开vscode&#xff0c;打开设置UI 或是设置JSON文件&#xff0c;找到相关设置项方式1&#xff1a;通过打开settings.json的UI界面 设置:方式2&#xff1a;通过打开设置settings.j…

音视频开发之旅(69)-SD图生图

目录 1. 效果展示 2. ControlNet介绍 3. 图生图流程浅析 4. SDWebui图生图代码流程 5. 参考资料 一、效果展示 图生图的应用场景非常多&#xff0c;比较典型的应用场景有风格转化&#xff08;真人与二次元&#xff09;、线稿上色、换装和对图片进行扩图等&#xff0c;下面…

【前沿热点视觉算法】-RGB-D显著目标检测的边缘感知多模态变压器

计算机视觉算法分享。问题或建议&#xff0c;请文章私信或者文章末尾扫码加微信留言。 1 论文题目 RGB-D显著目标检测的边缘感知多模态变压器 2 论文摘要 RGB-D显著目标检测&#xff08;SOD&#xff09;近年来引起了广泛的关注。特别是&#xff0c;变压器已被使用&#xff0c;并…

vmware安装centos 7.9 操作系统

vmware安装centos 7.6 操作系统 1、下载centos 7.9 操作系统镜像文件2、安装centos 7.9 操作系统3、配置centos 7.6 操作系统3.1、配置静态IP地址 和 dns3.2、查看磁盘分区3.3、查看系统版本 1、下载centos 7.9 操作系统镜像文件 本文选择centos 7.9 最小化安装镜像包 这里选…

C++ //练习 8.7 修改上一节的书店程序,将结果保存到一个文件中。将输出文件名作为第二个参数传递给main函数。

C Primer&#xff08;第5版&#xff09; 练习 8.7 练习 8.7 修改上一节的书店程序&#xff0c;将结果保存到一个文件中。将输出文件名作为第二个参数传递给main函数。 环境&#xff1a;Linux Ubuntu&#xff08;云服务器&#xff09; 工具&#xff1a;vim 代码块 /********…

pthread_cond_timedwait()函数

绝对时间&#xff1a;相对于1970年1月1日0时0分0秒 相对时间&#xff1a;相对于当前时间&#xff0c;如sleep(3);相对于当前&#xff0c;过3s.

RK3568平台开发系列讲解(Linux系统篇)字符设备驱动:主设备和次设备

🚀返回专栏总目录 文章目录 一、主设备和次设备的概念二、设备号的分配和释放沉淀、分享、成长,让自己和他人都能有所收获!😄 字符设备通过字符(一个接一个的字符)以流方式向用户程序传递数据,就像串行端口那样。字符设备驱动通过/dev目录下的特殊文件公开设备的属性和…

STM32单片机基本原理与应用(八)

温度传感器实验 实验内容&#xff1a; 单片机通过代码模拟1-Wire总线并对DS18B20进行读写&#xff0c;并在TFTLCD屏幕上显示当前实时温度。 电路原理图&#xff1a; 1-Wire总线 1-Wire总线&#xff1a;即单总线协议&#xff0c;采用单根信号线&#xff0c;既传输时钟&#…

模型 OIIC(目标、障碍、洞察、挑战)

系列文章 分享 模型&#xff0c;了解更多&#x1f449; 模型_总纲目录。沟通方案工具。 1 OIIC(目标、障碍、洞察、挑战)模型的应用 1.1 OIIC 驱动的汽车配件渠道优化 一家知名的汽车配件制造商&#xff0c;旗下品牌拥有众多产品&#xff0c;其销售渠道广泛&#xff0c;不仅在…

USB Micro引脚及相应原理图绘制

前言&#xff1a;博主为实现绘制USB Micro输入口原理图&#xff0c;首先在 GD32F103XX的数据手册中找到引脚的功能描述&#xff0c;找到USBDM与USBDP功能&#xff0c;分别为引脚PA11与引脚PA12。然后进行相应的原理图绘制。 * USBDM。USBDM 引脚是与通用串行总线 (Universal Se…

GPT Pilot - 编写 95% 代码的开发工具!

在这篇博客介绍了GPT-pilot的研发细节&#xff0c;原作者将探讨GPT Pilot的技术内核 —— 一款基于GPT-4编写的开发工具&#xff0c;可以生成生产使用代码的应用。 你有没有想过&#xff0c;95%的应用代码&#xff0c;可以由AI编写&#xff0c;就像《钢铁侠》里的贾维斯一样&a…

人工智能在测绘行业的应用与挑战

目录 一、背景 二、AI在测绘行业的应用方向 1. 自动化特征提取 2. 数据处理与分析 3. 无人机测绘 4. 智能导航与路径规划 5. 三维建模与可视化 6. 地理信息系统&#xff08;GIS&#xff09;智能化 三、发展前景 1. 技术融合 2. 精准测绘 3. 智慧城市建设 4. 可…

ElasticSearch之bool多条件查询

写在前面 在实际的业务场景中&#xff0c;不可能只是简单的单值查询 &#xff0c;更多的是n个条件的综合查询&#xff0c;就像下面的搜索&#xff1a; 针对这种场景我们就需要依赖于bool查询了&#xff0c;本文就一起来看下这部分的内容。 1&#xff1a;bool查询介绍 bool查…

推荐Miaoo朋友圈程序全开源版源码

Miaoo朋友圈的全开源程序源码提供了一套完整的解决方案&#xff0c;允许用户在前台轻松发布图文、视频和音乐内容。同时&#xff0c;用户可以设置地理位置信息&#xff0c;或者选择自定义位置。此外&#xff0c;系统支持将发布的内容设置为广告模式&#xff0c;并通过站内消息或…

RK3568平台开发系列讲解(Linux系统篇)字符设备驱动:分配和注册字符设备

🚀返回专栏总目录 文章目录 一、分配和注册字符设备二、file_operations沉淀、分享、成长,让自己和他人都能有所收获!😄 一、分配和注册字符设备 字符设备在内核中表示为struct cdev的实例。在编写字符设备驱动程序时,目标是最终创建并注册与struct file_operations关联…

【海贼王的数据航海:利用数据结构成为数据海洋的霸主】顺序表

目录 1 -> 线性表 2 -> 顺序表 2.1 -> 概念及结构 2.2 -> 接口声明 2.3 -> 接口实现 2.3.1 -> 初始化 2.3.2 -> 销毁 2.3.3 -> 检查 2.3.4 -> 打印 2.3.5 -> 尾插 2.3.6 -> 头插 2.3.7 -> 尾删 2.3.8 -> 头删 2.3.9 ->…

C习题001:顺子日期【仅供参考】

题目&#xff1a;小明特别喜欢顺子。顺子指的是连续的三个数字&#xff1a;123、456等。顺子日期指的就是在日期的yyyymmdd表示法中&#xff0c;存在任意连续的三位数是一个顺子的日期。例如20220123就是一个顺子日期&#xff0c;因为它出现了一个顺子&#xff1a;123&#xff…

Langchain-Chatchat部署总结

项目地址&#xff1a; https://github.com/chatchat-space/Langchain-Chatchat 整体安装比较方便&#xff0c;在阿里云购买云主机&#xff0c;购买的国外站点机器&#xff0c; 该项目运行最佳坏境为 Linux Ubuntu 22.04.5Python 版本 3.11.7CUDA 版本: 12.1torch2.1.2 使…

2024年怎么购买买 FL Studio 21最便宜

随着电子音乐的日益普及&#xff0c;越来越多的人开始尝试制作自己的音乐。而其中一个常用的音乐制作软件就是FL Studio。那么&#xff0c;对于刚入坑的萌新来说&#xff0c;如何选择FL Studio的版本呢&#xff1f; 很多打算入手正版FL Studio的新手朋友都会纠结一个问题&#…