c++11-消息总线库

Linux进程内消息总线设计 Windows平台进程内消息总线 文章目录Windows平台进程内消息总线如果没有消息总线,会产生什么问题死循环包含关系高耦合、低内聚消息总线结构图原理生产者与总线的关系总线与消费者的关系Linux进程内消息总线设计使用进程间实时信号来实现进程内消息总线参考文档整体流程主线程注册总线消息处理函数生产者线程产生并发送消息到总线接收并处理消息总线接收到消息总线消息处理函数消费者总线消息处理虚函数消费者... 阅读详情

消息总线

对象间只通过消息来联系,不通过直接的依赖或者关联。消息总线将复杂的关系简化,降低复杂度。

消息总线关键技术

1)通用的消息定义

让所有额对象都通过消息来联系,定义一种通用的消息格式

2)消息的注册

让所有对象都可以注册感兴趣的消息

3)消息分发

通过消息总线分发消息,让所有的接受者都能接收到并处理消息

通用消息的定义

消息的构成=消息的主题+泛型函数

消息主题:用于对消息接受者进行分组,只有对主题感兴趣的接受者,才可以收到消息

泛型函数:用于消息的接收者,所有具备该函数的对象都可以接收消息,std::function<R(Args...)>

消息注册

告诉总线,该对象对某种消息感兴趣,希望接收到某种主题和类型的消息。总线内部维护了一个消息列表,需要发送消息时,遍历这个列表,查找是否有合适的消息和消息接收者,找到合适的接收者后再广播消息。

1.lambda表达式转换为std::function

2.保存注册的消息

消息分发

主题对象希望接收者对象收到消息时,会通过消息总线发送消息,消息的本质是std::function,在发送消息前先创建消息,创建后再发送,消息总线会查找内部的容器,看看那些对象对这个消息感兴趣,只有注册了这个消息的对象才能收到消息。

 

消息总线的设计思想

function_traits:

#pragma once
#include<functional>
#include<tuple>

template<typename T>
struct function_traits;

template<typename Ret,typename... Args>
struct function_traits<Ret(Args...)>
{
public:
    enum {arity=sizeof...(Args) };
    typedef Ret function_type(Args...);
    typedef Ret return_type;

    using stl_function_type = std::function<function_type>;

    typedef Ret(*pointer)(Args...);

    template<size_t I>
    struct args {
        static_assert(I < arity, "index is out of range");
        using type = typename std::tuple_element < I, std::tuple<Args...>>::type;
    };
};
template<typename Ret, typename... Args>
struct function_traits<Ret(*)(Args...)>:function_traits<Ret(Args...)>
{

};
template<typename Ret, typename... Args>
struct function_traits<std::function<Ret(Args...)>> :function_traits<Ret(Args...)>
{

};

#define FUNCTION_TRAITS(...)\
template<typename ReturnType, typename ClassType, typename ... Args>\
struct function_traits<ReturnType(ClassType::*)(Args...)>:function_traits<ReturnType(Args...)>{ };\

FUNCTION_TRAITS()
/*
FUNCTION_TRAITS(const)
FUNCTION_TRAITS(volatile)
FUNCTION_TRAITS(const volatile)*/
/*
template<typename Callable>
struct function_traits :function_traits<decltype(&(Callable::(operator())))> {};*/

/*
template<typename Function>
typename function_traits<Function>::stl_function_type to_function(const Function & lambda) {
    return static_cast<typename function_traits<Function>::stl_function_type>(lambda);
}*/

template<typename Function>
typename function_traits<Function>::stl_function_type to_function(Function && la) {
    return static_cast<typename function_traits<Function>::stl_function_type>(std::forward<Function>(la));
}
/*
template<typename Function>
typename function_traits<Function>::pointer to_function(const Function & lambda) {
    return static_cast<typename function_traits<Function>::pointer>((lambda));
}*/

 

messagebus:

#pragma once
#include"function_traits.h"
#include"any.h"
#include<string>
#include<map>

class MessageBus {
public:
    template<typename F>
    void Attach(F&& f, const std::string& strTopic = "") {
        auto func = to_function(std::forward<F>(f));
        Add(strTopic, std::move(func));
    }
    template<typename R>
    void sendReq(const std::string& strTopic = "") {
        using function_type = std::function<R()>;
        std::string strMsgType = strTopic + typeid(function_type).name();
        auto Range = m_map.equal_range(strMsgType);
        for (Iterator it = Range.first; it!= Range.second; it++) {
            auto f = it->second.AnyCast<function_type>();
            f();
        }

    }
    template<typename R,typename ... Args>
    void sendReq(Args ... args,const std::string& strTopic = "") {
        using function_type = std::function<R(Args...)>;
        std::string strMsgType = strTopic + typeid(function_type).name();
        auto Range = m_map.equal_range(strMsgType);
        for (Iterator it = Range.first; it !=Range.second; it++) {
            auto f = it->second.AnyCast<function_type>();
            f(std::forward<Args>(args)...);
        }

    }
    template<typename R, typename ... Args>
    void Remove(Args ... args, const std::string& strTopic = "") {
        using function_type = std::function<R(args)>;
        std::string strMsgType = strTopic + typeid(function_type).name();
        auto Range = m_map.equal_range(strMsgType);
        m_map.erase(Range.first,Range.second);
    }
private:
    template<typename F>
    void Add(const std::string& strTopic, F&& f) {
        const std::string strMsgType = strTopic + typeid(f).name();
        std::pair<std::string, Any> p(strMsgType, std::forward<F>(f));
        m_map.insert(std::move(p));
    }
    std::multimap<std::string, Any> m_map;
    typedef std::multimap<std::string, Any>::iterator Iterator;

};

 

 

使用C++11实现的非阻塞消息总线message_bus 消息总线(Message Bus)作为一种重要的通信模式,被应用于解耦系统中的组件,实现异步通信和事件驱动架构。 本文将介绍如何使用C++11实现一个非阻塞消息总线,通过异步处理消息来提高系统的并发性能和响应速度。 阅读详情

相关推荐

构建你的智能家居消息中枢:用 C++11 和 paho-mqtt-cpp 实现 MQTT 消息总线

本文介绍了如何使用C++11和paho-mqtt-cpp库构建智能家居MQTT消息总线系统。系统采用事件驱动架构实现模块解耦,通过统一的Event事件结构体和EventBus抽象接口,支持多种通信后端。重点展示了MQTT后端的实现细节,包括连接管理、消息发布/订阅机制和线程安全处理。该系统具有高扩展性,可方便集成新模块和通信协议,为智能家居系统提供高效可靠的消息中枢。文中提供了完整代码示例和项目结构,涵盖事件类型定义、接口设计和实际应用场景。

向前走走吧 2306

C++11的消息总线

一、什么是消息总线 在大规模的软件开发过程中,对象很多,关联关系非常复杂,如果没有统一的、简洁的方法去管理这些对象关系,会导致对象关系复杂,后期维护困难。 基于消息总线技术可以解决这些问题。对象之间只通过消息联系,不是通过直接的依赖或者关联。在消息总线中,对象是通过消息来联系,消息即是对象的关系,只需要在消息总线中管理这些消息,不用关心具体哪些对象之间有关联,便于统一管理。 二、消息总线包含的内容 通用的消息定义 定义一种通用的消息格式,让所有的对象都能接受。 通用的消息类型完整的定义是主题+泛

sinat_31608641的博客 3556

libbus:轻量级,简单的并发消息总线库

libbus 一个根本上轻便且简单的并发消息总线库。 它有什么作用? libbus提供用于消息传递的共享总线。 客户端可以注册回调以从总线接收消息。 任何用户都可以向所有注册的客户端(广播)或特定的客户端发送消息。 该库利用GCC的原子内建函数来确保在多线程环境中进行无锁同步。 可以在找到更多详细信息。 编译中 只需使用make static将其编译为静态库。 您可以通过将其与库链接来从程序中使用libbus : gcc <your> libbus.a -I<path>/src/ -latomic 。 用法 用例 用例的示例是具有多个线程的环境,这些线程执行队列中的作业。 使用libbus ,每个线程都可以注册一个回调,该回调将接收到的消息推送到该线程的队列中。 在这种情况下,可以将bus_register的ctx参数设置为指向该线程的队列。

C++编程:实现一个简单的消息总线

本文将介绍如何使用 C++ 编写一个改进的消息总线系统,其中包括以下功能: - **消息发布**:发布消息给所有订阅该消息的订阅者。 - **消息订阅**:允许订阅者订阅感兴趣的消息,并注册回调函数以便处理接收到的消息。 - **定时任务调度**:支持周期性的任务调度,例如定时检查超时的订阅。 - **超时管理**:每个订阅可以设置超时回调,如果在指定时间内未收到消息,将执行该回调。

Where there is life, there is hope. 1458

message_bus:小消息总线示例

消息总线 这是一个非常基本的实验,以查看我是否可以实现消息传递总线以通过消息传递总线将消息发送到其他模块。 建造 mkdir build cmake make 执照 该代码是zlib / png下的许可。 随意使用此功能。 尚·塞巴斯蒂安·福特克斯(Jean-SébastienFauteux)

UE 动态获取 资源缩略图 下载到本地或返回图片信息

UE 动态加载资源缩略图 返回图片信息或保存到本地

qq_46080252的博客 1937

C++11开发的消息总线库

消息总线是一种降低耦合的一种技术,对象间只通过消息练习,不通过依赖或者关联。将复杂对象关系简化,降低复杂度,提高程序的维护性。 消息总线是一种解耦合的程序的设计方式,可以让对象之间的依赖和继承用消息注册来联系。 消息总线的关键技术 1、通用消息的定义 本质其实是让所有的对象之间的联系都通过消息来联系,所以,要定义一种通用的消息格式,让所有的对象都能使用接受。 2、消息的注册 让所有的对象注册感兴趣的消息。 3、消息分发 通过消息总线分发消息,让所有的接收者能收到并处理消息。 接下来就围绕上述这三点进行详细的

qq_42317817的博客 1276

HWSD2.0土壤数据处理实战:从下载到属性提取全流程解析

本文详细解析了HWSD2.0全球土壤数据库从数据下载、属性筛选到GIS空间连接与提取的全流程实战方法。重点介绍了如何利用ArcGIS Pro等工具,将土壤单元编码与黏粒含量等属性表关联,最终生成全球土壤属性专题栅格图,为农业规划与生态研究提供关键数据支撑。

weixin_29214691的博客 610

1 Studying《深入应用C++11》

传统的一个请求一个线程处理,在处理大量并发任务时,会导致大量的线程创建和销毁,消耗过多的系统资源。线程池可以解决这个问题。本章介绍的是半同步半异步线程池,线程池结构图如图9-1:图9-1 半同步半异步线程池第一层是同步服务层,它处理来自上层的任务请求。上层的请求可能是并发的,这些请求不是马上被处理,而是将这些请求放到一个同步队列里。第二层是排队层,即同步队列。第三层是异步服务层,多个线程从同步队列里取出任务并处理。AOP(Aspect-Oriented Programming,面向方面编程)。

u012906122的专栏 1149

英飞凌TC377的Flash管理、UCB配置与HSM安全机制解析

本文深入解析了英飞凌TC377微控制器的Flash存储结构、UCB配置机制与HSM安全模块。详细阐述了带Cache与不带Cache的PFlash地址访问差异、利用SOTA与AB Swap实现无感OTA更新的原理,以及如何通过UCB安全配置启动流程与写保护。重点剖析了HSM硬件安全模块在密钥管理、安全启动与安全OTA中的核心作用,为开发高可靠性嵌入式系统提供实战指南。

weixin_29170327的博客 523

树莓派与stm32通信超详细解答过程

笔者之前发过关于stm32与openmv通信的教程,在学习了几天opencv后,想实现树莓派4B与stm32进行通信。于是上网查询资料,最后实现了两者之间的通信,相信这对大多数电赛人都很有帮助,opencv的识别效果是远高于openmv以及K210的。在此我参考了以下资料辅助我学习,大家可以参考。基于树莓派4B与STM32的UART串口通信实验(代码开源)_树莓派4b串口波特率-优快云博客。

Halcyon0804的博客 5465

(转发)一个通用的C++ 消息总线框架

注:转自https://www.cnblogs.com/qicosmos/archive/2013/04/28/3048919.html 应用开发过程中经常会处理对象间通信的问题,一般都是对象或接口的依赖和引用去实现对象间的通信,这在一般情况下是没问题的,但是如果相互通信的对象很多,可能会造成对象间的引用关系像蜘蛛网一样,这样会导致对象关系很复杂,难以维护的问题,解决这个问题的一个好方...

weixin_30432579的博客 481

从转发时钟到嵌入式时钟:CDR、CTLE与DFE在高速串行链路中的协同演进

本文深入探讨了高速串行链路中CDR、CTLE与DFE技术的协同演进。从转发时钟到嵌入式时钟的转变,详细分析了CDR的工作原理与实现架构,以及CTLE和DFE在信道损耗补偿和ISI干扰消除中的关键作用。通过实战案例展示了这些技术在28Gbps至112Gbps SerDes设计中的优化策略与性能提升。

weixin_42539414的博客 294

对象的消息总线——C++11

对象的消息总线——C++11 学习《深入应用C++11 代码优化与工程级应用》 什么是消息总线 对象之间的关系一般有:依赖、关联、聚合、组合和继承。 在大规模的软件开发过程中,对象很多,关联关系非常复杂,如果没有统一的、简洁的方法去管理这些对象关系,会导致对象关系复杂,后期维护困难。 基于消息总线技术可以解决这些问题。对象之间只通过消息联系,不是通过直接的依赖或者关联。在消息总线中,对象是通过消息来联系,消息即是对象的关系,只需要在消息总线中管理这些消息,不用关心具体哪些对象之间有关联,便于统一

Skynet的博客 716

Python速成指南:进阶篇

欢迎来到Python速成指南的进阶篇。如果你已经完成了基础篇的学习(Python速成指南:从零开始的编程之旅-优快云博客),并且对Python的基本概念有了扎实的理解,那么你已经为进入更深层次的Python世界做好了准备。在这个进阶篇中,我们将深入探讨Python的高级特性,并着重于如何在实际工作中应用这些知识。深入理解Python的高级特性掌握在实际项目中常用的技巧和最佳实践提高代码质量和性能了解Python在各个领域的专业应用让我们开始这段激动人心的Python进阶之旅吧!

weixin_44067082的博客 2337

RK3568平台(电源篇)电源域IO配置

在kernel之前需要修改电源域,主控电源域的IO电平要与对接外设芯片的IO电平匹配,还要注意软件的电压配置要跟硬件的电压一致,否则,最坏的情况可能会导致IO的损坏。其实就是管理 IO 输出的电平;假如硬件上 IO 电源域配置为 3.3V,则 IO 输出最大电平为 3.3V;同理 IO 电源域硬件配置为 1.8V,则 IO 输出最大电平是 1.8V;这样有利于 IO 电平的灵活配置;

weixin_49303682的博客 3478

c++11实现的一个消息总线框架

最近在看C++11的特性,然后按照网上的例子实现了一个消息总线框架。https://github.com/hejiajie1989/MessageBus项目里README文档里有详细的设计说明,使用的时候 g++ test.cpp -o test -std=c++11 g++ TestMessageBus.cpp -o TestMessageBus -std=c++11

Aaron的专栏 3614

JavaScript实现斗地主(附完整源码)

JavaScript实现斗地主(附完整源码)

希望我的博客,能帮上你解决学习中工作中所遇到的问题 1503

【C++11】对象消息总线(2)

本系列文档从属于:C++11应用实践系列 部分Demo和结论引用自&amp;amp;lt;深入应用C++11代码优化与工程&amp;amp;gt;这本书 消息总线消息总线设计思想 前一节已经介绍了,如何承载消息,本节将会实现,消息保存和分发。 消息保存:由于消息类型有不同的返回值以及入参,这里可以使用之前介绍的Any作为消息载体 消息分发:这个就比较容易了,取出合适的函数对象(消息)直接调用即可。 消息总线设计思想 消息...

柠檬柠檬C的博客 2152

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

【C++11】对象消息总线(1)

本系列文档从属于:C++11应用实践系列 部分Demo和结论引用自&amp;amp;amp;amp;amp;amp;amp;lt;深入应用C++11代码优化与工程&amp;amp;amp;amp;amp;amp;amp;gt;这本书 什么是消息总线? 对象的关系之间一般有:依赖、关联、聚合、组合和继承,他们的耦合程度也是依次加强! 未完待续。。先整理文章...

柠檬柠檬C的博客 4100

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

消息总线之模型重构

前段时间重新对消息总线的通信模型进行设计&重构,这篇文章谈谈其中的一些想法。消息总线对RabbitMQ的官方java client进行了定制、简化。

VinoYang的专栏 3372

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

(原创) 一个通用的C++ 消息总线框架

c++11 boost技术交流群:296561497,欢迎大家来交流技术。 应用开发过程中经常会处理对象间通信的问题,一般都是对象或接口的依赖和引用去实现对象间的通信,这在一般情况下是没问题的,但是如果相互通信的对象很多,可能会造成对象间的引用关系像蜘蛛网一样,这样会导致对象关系很复杂,难以维护的问题,解决这个问题的一个好方法是通过消息总线去解耦对象间大量相互引用的紧耦合的关系。 设计思路:被...

weixin_34217711的博客 560

现代C++实现消息总线:解耦利器与实战指南

在软件架构中,模块解耦是提升可维护性和扩展性的核心设计原则。其基本原理是通过引入中间层来隔离组件间的直接依赖,从而降低耦合度。这一思想的技术价值在于能够构建更灵活、更易演进的系统。在C++工程实践中,消息总线(Message Bus)是实现模块解耦的一种经典且高效的模式,它允许组件通过发布和订阅消息进行通信,而非直接调用。这种模式广泛应用于事件驱动系统、插件架构以及需要动态响应的应用场景。本文聚焦于如何利用现代C++(C++11/14)的特性,如`std::function`、可变参数模板和类型擦除,从零开

weixin_32183107的博客 260
上一篇: c++11线程池
下一篇: Cmake教程
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值