第三方库介绍——nanomsg(高性能通信库)

news2024/9/22 7:21:58

一、nanomsg介绍

  • NanoMsg是一个Socket的通讯库,使用C语言编写实现的,这样就可以适用于多种操作系统,而且几乎不需要什么依赖,可扩展并且能易于使用。Nanomsg提供了几种常见的通信模式 ( 也称为“可扩展性协议” ) 是构建分布式系统的基本框架。 通过组合它们,可以创建广 泛的分布式应用程序。nanomsg 高性能通信库_NanoMsg框架|NanoMsg的简介

  • 使用nanomsg可以实现线程间通信,nanomsg库又很轻量级,对于嵌入式程序编程真的非常好用。使用nanomsg库实现多线程之间的通信(一)

可扩展性协议类型

  • PAIR (配对模式):简单的一对一沟通
  • BUS (总线模式):简单的多对多通信
  • REQREP (请求/回复模式):允许构建无状态集群来处理用户请求
  • PUBSUB (扇入模式):将消息分发给订阅消息的用户
  • PIPELINE (扇出模式):汇总来自多个来源的消息,并在许多目的点之间进行负载平衡
  • SURVEY (调查模式):允许一次查询多个应用程序的状态

可扩展协议是在网络通信协议之上实现的,当前版本nanomsg支持一下网络协议:

  • INPROC:单进程内通信;

  • IPC:单机内多进程的通信;

  • TCP:通过tcp协议的网络通信;

参考博文:C++网络库探索(二)

二、编译与安装(x86)

下载地址:nanomsg的github仓库网址
下载如下版本:
在这里插入图片描述
复制到Ubuntu中,压缩

tar zxvf nanomsg-1.1.4.tar.gz

进入文件目录

cd nanomsg-1.1.4

创建编译目录build,并移动到build目录

mkdir build && cd build

创建x86_lib文件夹

mkdir x86_lib

根据CMakeLists.txt文件,生成Makefile

cmake .. -DCMAKE_INSTALL_PREFIX=$PWD/x86_lib

编译

cmake --build .

测试驱动程序

ctest .

ctest可执行文件是CMake测试驱动程序

  • 使用enable_testing()和add_test()命令的项目创建的cmake生成构建树具有测试支持。此程序将运行测试并报告结果。
  • ctest 使用教程:cmake:命令行工具ctest

在这里插入图片描述

调用本地的构建系统执行 install 这个目标,将生成的库和头文件安装到系统上,其实就是把静态库和动态库以及头文件拷贝到系统库文件目录下,如果前面指定安装位置为build/x86_lib,至此,就可以和使用其他系统库一样,使用nanomsg库了

sudo cmake --build . --target install

为了让这些由某个工程后生成的动态链接库为系统所共享,还需运行动态链接库的管理命令–ldconfig。(直接sudo ldconfig即可)。linux下面的sudo ldconfig命令

sudo ldconfig

进入build/x86_lib/lib目录。查看是否有libnanomsg.so相关文件,查看生成的动态库是否是x86架构的:

readelf -h libnanomsg.so

在这里插入图片描述

三、编译与安装(arm)

Linux主机:ubuntu-18.04

交叉编译器:arm-buildroot-linux-gnueabihf

开发板kernel:Linux 5.4.0-150-generic x86_64

开发板:100ASK_STM32MP157_PRO开发板

在nanomsg根目录下的CMakeLists.txt文件里加上交叉编译器设置:
在这里插入图片描述

然后后输入如下命令:

mkdir build && cd build
mkdir arm_lib
cmake .. -DCMAKE_INSTALL_PREFIX=$PWD/arm_lib
cmake --build .
sudo cmake --build . --target install
sudo ldconfig

进入build/arm_lib/lib目录。查看是否有libnanomsg.so相关文件,查看生成的动态库是否是arm架构的:

readelf -h libnanomsg.so

在这里插入图片描述

通过编译得到的是动态库,如果需要编译为静态库调用。只要修改一下CMakeLists.txt中编译规则

四、测试与使用

演示进程间通信的例子
nanomsg_server.c:

#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <nanomsg/pair.h>
#include <nanomsg/bus.h>
#include <nanomsg/nn.h>
 
#define BUF_LEN  100
 
char *url = "tcp://127.0.0.1:2021";
 
int main(void)
{
 int server_sock = 0;
 char buf[BUF_LEN] = {0};
 
 if (server_sock = nn_socket (AF_SP, NN_PAIR) < 0)
 {
  printf("create server socket failed!\n");
  return -1;
 }
 
 if (nn_bind(server_sock, url) < 0) 
 {
  printf("bind server sock failed!\r\n");
  nn_close(server_sock);
  return -1;
 }
 printf("server init success!\n");
 
 while (1)
 {
  if (nn_recv(server_sock, buf, sizeof(buf), 0) < 0) 
  {
   printf("recv failed!\n");
   nn_close(server_sock);
   exit(EXIT_FAILURE);
  }
  else
  {
   printf("recieve client msg: %s\r\n", buf);
   if (nn_send(server_sock, buf, sizeof(buf), 0) < 0)
   {
    printf("send failed!\r\n");
    nn_close(server_sock);
    exit(EXIT_FAILURE);
   }
  }
 }
 
 nn_close(server_sock);
 
 return 0;
}

nanomsg_client.c:

#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <nanomsg/pair.h>
#include <nanomsg/bus.h>
#include <nanomsg/nn.h>
 
#define BUF_LEN  100
 
char *url = "tcp://127.0.0.1:2021";
 
int main(void)
{
 int client_sock = 0;
 char buf[BUF_LEN] = {0};
 
 if (client_sock = nn_socket (AF_SP, NN_PAIR) < 0)
 {
  printf("create server socket failed!\n");
  return -1;
 }
 
 if (nn_connect(client_sock, url) < 0) 
 {
  printf("connect server sock failed!\r\n");
  nn_close(client_sock);
  return -1;
 }
 
 printf("client init success!\n");
 
 while (1)
 {
        scanf("%s", buf);
  if (nn_send(client_sock, buf, sizeof(buf), 0) < 0)
  {
   printf("send failed!\r\n");
   nn_close(client_sock);
  }
 
        memset(buf, 0, BUF_LEN);   
 
  if (nn_recv(client_sock, buf, sizeof(buf), 0) > 0) 
  {
   printf("recieve server msg: %s\r\n", buf);
  }
        memset(buf, 0, BUF_LEN);   
 }
 
 nn_close(client_sock);
 
 return 0;
}

编译:

gcc nanomsg_server.c -o nanomsg_server -I /home/book/Desktop/nanomsg/nanomsg-1.1.4/build/x86_lib/include -L /home/book/Desktop/nanomsg/nanomsg-1.1.4/build/x86_lib/lib -lnanomsg
gcc nanomsg_client.c -o nanomsg_client -I /home/book/Desktop/nanomsg/nanomsg-1.1.4/build/x86_lib/include -L /home/book/Desktop/nanomsg/nanomsg-1.1.4/build/x86_lib/lib -lnanomsg

修改环境变量(临时):

export LD_LIBRARY_PATH=/home/book/Desktop/nanomsg/nanomsg-1.1.4/build/x86_lib/lib:$LD_LIBRARY_PATH

运行:

在这里插入图片描述

嵌入式大杂烩 | 一个高性能通信库的简单使用分享

参考博文:

nanomsg关于多线程与多进程间通信的实现

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

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

相关文章

C++ 第一弹入门基础

目录 目录 1.关键字 2.命名空间 3.标准IO输入输出 4.缺省参数 5.函数重载 6.引用 7.内联函数 1.关键字 c98的关键字一共有63个 在之后用的时候都会再次详细介绍 2.命名空间 2.1什么是命名空间&#xff0c;为什么要有他&#xff1f; 在c中为了避免相同名字的变量&am…

torchvision.utils.save_image()保存tensor显示图片异常问题解决

用torchvision.utils.save_image()保存图片时出现异常 有些像素点会显示为全黑&#xff08;灰度图&#xff09;&#xff0c;如下图所示&#xff0c;第一张和第三张图 刚开始以为是图像数据分布范围的问题&#xff0c;在保存之前输出图像tensor的最大max和最小min值&#xff0c;…

【Python 基础篇】Python 模块与包

文章目录 引言一、模块与包概述二、模块的导入和使用三、包的组织和导入四、实际应用场景五、总结 引言 在Python编程中&#xff0c;模块和包是组织和复用代码的重要工具。随着项目规模的增长&#xff0c;将代码按照功能模块化并组织成包&#xff0c;可以提高代码的可读性、可…

吴恩达ChatGPT《Building Systems with the ChatGPT API》笔记

1. 课程介绍 使用ChatGPT搭建端到端的LLM系统 本课程将演示使用ChatGPT API搭建一个端到端的客户服务辅助系统&#xff0c;其将多个调用链接到语言模型&#xff0c;根据前一个调用的输出来决定使用不同的指令&#xff0c;有时也可以从外部来源查找信息。 课程链接&#xff1a…

设计模式之桥接模式笔记

设计模式之桥接模式笔记 说明Bridge(桥接)目录桥接模式示例类图视频文件接口avi视频文件类rmvb视频文件类抽象的操作系统类windows类mac类测试类 说明 记录下学习设计模式-桥接模式的写法。JDK使用版本为1.8版本。 Bridge(桥接) 意图:将抽象部分与其实现部分分离&#xff0c…

用微分方程描述的连续时间滤波器举例

用微分方程描述的连续时间滤波器举例 在许多应用中&#xff0c;频率选择性滤波器是用线性常系数微分或差分方程描述的线性时不变系统来实现的。这有许多理由&#xff0c;例如很多具有滤波作用的物理系统都是由微分或差分方程表征的。这方面的一个很好的例子就是在后续将研究的汽…

消息中间件相关知识简介

一、消息中间件相关知识 1、概述 消息队列已经逐渐成为企业IT系统内部通信的核心手段。它具有低耦合、可靠投递、广播、流量控制、最终一致性等一系列功能&#xff0c;成为异步RPC的主要手段之一。当今市面上有很多主流的消息中间件&#xff0c;如老牌的ActiveMQ、RabbitMQ&am…

Python 基础(十五):模块

❤️ 博客主页&#xff1a;水滴技术 &#x1f338; 订阅专栏&#xff1a;Python 入门核心技术 &#x1f680; 支持水滴&#xff1a;点赞&#x1f44d; 收藏⭐ 留言&#x1f4ac; 文章目录 一、什么是模块二、自定义模块三、引用其它模块3.1、使用 import 引用模块3.2、使用 f…

揭秘Java 8的新特性:Stream API的使用和实践

&#x1f389;&#x1f389;&#x1f389;点进来你就是我的人了博主主页&#xff1a;&#x1f648;&#x1f648;&#x1f648;戳一戳,欢迎大佬指点! 欢迎志同道合的朋友一起加油喔&#x1f93a;&#x1f93a;&#x1f93a; 目录 1. 集合处理数据的弊端 2. Stream流式思想概述…

VN8911/VN8912(A)/VN8914/VN8910(A)上安装驱动

问题&#xff1a; 如何在 VN8911、VN8912(A) 或 VN8914 设备上安装驱动程序&#xff1f; 背景&#xff1a; VN8911、VN8912(A) 或 VN8914 设备 [下面概括为 VN8900 系列&#xff0c;不包括 VN8910(A)] 与 CANoe 一起使用时作为分布式实时系统运行 [参见下面的 CANoe 11.0 和 V…

vue插槽概念解释

官方文档 https://cn.vuejs.org/guide/introduction.html 什么是插槽 在 Vue.js 中&#xff0c;插槽&#xff08;Slots&#xff09;是一项非常有效的功能&#xff0c;它允许我们在组件中预留一个占位符&#xff0c;供父组件插入自定义的内容。 具体来说&#xff0c;当一个组件…

Linux和Shell:开源力量与命令行之美

目录 一、概述二、Linux的简单介绍三、Shell的简单介绍四、Linux和Shell的应用领域五、Shell编程结语&#xff1a; 一、概述 Linux和Shell是开源世界中不可或缺的两个重要组成部分。Linux作为一种自由和开放的操作系统&#xff0c;以其稳定性、安全性和可定制性而备受推崇。而S…

【ProNoC】Chap.1 ProNoC生成2x2的mesh型的4核片上网络系统;实现NoC的RTL设计

【ProNoC】Chap.1 ProNoC生成2x2的mesh型的4核片上网络系统&#xff1b;实现NoC的RTL设计 0. NoC多核片上网络生成器ProNoCProNoC的功能实现 1. 生成一个叫做Mor1kx SoC的单个Tile&#xff08;包含NI网络接口&#xff09;1.1 打开ProNoC用于生成Tile的GUI界面1.2 为Tile添加时钟…

Python基础篇(四):基本数据类型的学习和示例

Python基础篇(三)&#xff1a;基本语句的示例和说明 基本数据类型的学习和操作 1. 数值类型1.1 整数&#xff08;int&#xff09;1.2 浮点数&#xff08;float&#xff09;1.3 复数&#xff08;complex&#xff09; 2. 字符串类型2.1 字符串的定义2.2 转义字符2.3 多行字符串2…

Vue-几种插槽(slot)的使用

插槽(slot) 插槽在vue中是一种很常见的写法&#xff0c;让父组件可以向子组件指定位置插入html结构&#xff0c;也是一种组件间通信的方式 一共有三种分类&#xff1a;默认插槽、具名插槽、作用域插槽&#xff0c;下面一一根据案例改造说明 1 基本案例 首先编写一个基本的案…

12.1 物业管理项目中的新知识点

1.RESTful 2.雪花ID 3.mybatis的动态sql 很多时候需要实现多条件查询&#xff0c;手动判断拼接sql有些麻烦 mybatis提供了一个动态sql实现多条件查询的方法 3.1 if元素 使用if元素可以根据条件来包含或排除某个SQL片段 <select id"search" resultType"Hous…

OpenCV——实验结果输出《图像金字塔》和《图像轮廓》

1.高斯金字塔 img cv2.imread(./AM.png) print(img.shape) upcv2.pyrUp(img) cv_show(up,up)#只是将图片的大小改变了,并且是2倍2倍的增长。 print (up.shape) downcv2.pyrDown(img) cv_show(down,down) print(down.shape) up_downcv2.pyrDown(up) cv_show(up_down,np.hstack…

SSMP整合案例(4) Spring Boot整合MyBatis-Plus实现分页查询

文章 SSMP整合案例(3) 创建数据层并在测试类中运行数据库增删查改操作我们编写了MyBatis-Plus以Druid为数据源的方式 做了数据库的增删查改操作 那么 下面我们继续写 分页查询 我们 先写这样一段代码 bookDao.selectPage()selectPage就是BaseMapper提供给我们的分页查询函数 但…

【Spring Cloud + RabbitMQ 实现分布式消息总线】—— 每天一点小知识

&#x1f4a7; S p r i n g C l o u d R a b b i t M Q 实现分布式消息总线 \color{#FF1493}{Spring Cloud RabbitMQ 实现分布式消息总线} SpringCloudRabbitMQ实现分布式消息总线&#x1f4a7; &#x1f337; 仰望天空&#xff0c;妳我亦是行人.✨ &#x1f984; …

redis集群原理

redis是单线程&#xff0c;但是一般的作为缓存使用的话&#xff0c;redis足够了&#xff0c;因为它的读写速度太快了。 官方的一个简单测试&#xff1a; 测试完成了50个并发执行100000个请求。 设置和获取的值是一个256字节字符串。 结果:读的速度是110000次/s,写的速度是81000…