【问题标题】:Modern alternative to publisher subscriber pattern发布者订阅者模式的现代替代方案
【发布时间】:2014-07-31 19:06:33
【问题描述】:

我有一个 C++ Windows 应用程序。我正在处理发布者 - 订阅者的情况,其中我的一个类(发布者)定期生成数据并将其交给另一个类(订阅者),该类(订阅者)不断等待接收来自发布者的通知。我是设计模式的新手,我查找了发布者订阅者模型的常见实现,我注意到它们通常很旧,而且它们通常涉及维护指向对象的指针列表。我想知道是否有更好的方法来使用 C++ 11 对发布者订阅者模型进行编码。或者使用完全不同的模型来代替发布者 - 订阅者。 如果你能说出一些有趣的特性或方法,我会阅读它们的文档,编写一个实现并将其添加到这里以供进一步审查。

更新:我说过我会发布示例代码。首先,Jens 推荐的 Boost Signals 2 真的很有效。我的代码与http://www.boost.org/doc/libs/1_55_0/doc/html/signals2/tutorial.html上的初学者部分差别不大

【问题讨论】:

  • 问题没有变,解决方案也没有变。问题中不存在不同的考虑因素,但出于整体考虑:您不需要实现将数据从生产者移动到消费者的所有代码,您可以使用现有组件(具有外部同步)隐藏了数据结构本身的复杂性。
  • @DavidRodríguez-dribeas “您可以使用现有组件(具有外部同步的序列容器)”您能否详细说明一下,我对这一切都很陌生。同步是指处理并发相关的问题吗?或者,您的意思是外部机构将在其范围内同时拥有发布者和订阅者,因此将能够管理所有这些。所有这些都在一个线程中完成。
  • 对于最简单的解决方案(不一定是最好或最坏的解决方案),请考虑将同步队列结合 std::deque、互斥体和条件变量。发布者加锁,push_back,信号,消费者加锁,检查是否有数据并取走,或者条件变量是否没有等待。

标签: c++ design-patterns c++11 listener publish-subscribe


【解决方案1】:

看看一个信号库,例如Boost.Signals2libsigc++。它们提供了一个抽象来定义您的类中客户端可以连接的信号。存储连接等的所有逻辑都在那里实现。

【讨论】:

  • 有趣。我去看看,写个基本的代码,谢谢建议。
【解决方案2】:

您可以存储函数向量,这是一种快速而肮脏的方式:

template<class T>
class dispatcher
{
    std::vector<std::function<void(T)> > functions;
public:
    void subscribe(std::function<void(T)> f)
    {
        functions.push_back(f);
    }

    void publish(T x)
    {
        for(auto f:functions) f(x);
    }
};

这没有取消订阅(您必须为此使用地图)。

但是,这不是线程安全的。如果你想要线程安全,你应该Boost.Signals2

【讨论】:

    【解决方案3】:

    好吧,如果您想要现代的、真正现代的替代方案,也许除了 Boost.Signals2 之外,正如 Jens 所提到的,您可以尝试 functional reactive programming 范式。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-12-14
      • 2012-07-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-07
      • 2010-11-02
      相关资源
      最近更新 更多