首页 > 解决方案 > C++ 过滤器管道

问题描述

我想为我的应用程序开发一个过滤器管道。管道应该由任意数量的过滤器组成。

对于过滤器,我声明一个抽象基类,如下所示:

struct AbstractFilter {
    virtual void execute(const std::string& message) = 0;
    virtual ~AbstractFilter() = default;
}

每个过滤器都应该从这个基类继承并实现execute方法。像这样:

struct PrintMessage : public AbstractFilter {
    void execute(const std::string& message) override {
        std::cout << "Filter A " << message << '\n';
        //hand over message to next Filter

    }
}

struct Upper : public AbstractFilter {
    void execute(const std::string& message) override {
        std::string new_line;
        for (char c : line)
           new_line.push_back(std::toupper(c));
        //hand over message to next Filter
    }
}

struct WriteToFile : public AbstractFilter {
    void execute(const std::string& message) override {
        std::ofstream of{"test.txt"};
        of << message;
        of.close();
    }
}

编辑1:

消息应该从管道中的一个过滤器发送到下一个过滤器。例如,如果管道是这样的:

上 -- PrintMessage -- WriteToFile

消息应通过所有 3 个过滤器。(例如,如果Upper完成了他的工作,则应该将消息发送到PrintMessage等等)

在上面的例子中,如果消息Hello World被发送到管道,输出应该是:

Console:
HELLO WORLD
test.txt:
HELLO WORLD

编辑2:

过滤器仅更改给定消息的内容。类型没有改变。每个过滤器都应该使用例如字符串或给定的类。消息仅转发给一位收件人。

我现在的问题是如何连接这些过滤器?

我的第一个猜测是使用Queues. 所以每个过滤器都有一个InputOutput队列。为此,我认为每个过滤器都应该在它自己的内部运行,并在数据添加到他的队列Thread时收到通知。InputOutput比如FilterA的InputQueue也是FilterB的Queue)

我的第二个猜测是使用责任链模式,boost::signals2 因此 FilterB 例如连接到 FilterA 的信号。FilterA 在完成工作后调用这些过滤器。

两种解决方案哪个更灵活?或者有没有更好的方法来连接过滤器?

另一个问题是否也可以在一个线程内运行整个管道,以便我可以启动多个管道?(在示例中,有 3 个 FilterA-FilterB-FilterD 管道启动并运行?)

标签: c++multithreadingboostpipeline

解决方案


我相信责任链模式更简单,允许更简洁的代码和更大的灵活性。

您不需要第三方库来实现它。
您所说的过滤器实际上是处理程序。所有处理程序都实现一个通用接口,定义一个可以命名的方法,handle()甚至可以将对象作为参数来共享状态。每个处理程序都存储一个指向下一个处理程序的指针。它可能会或可能不会在其上调用该方法;在后一种情况下,处理停止,它充当过滤器

如果其中一些需要其他的输出作为输入,则并行运行流水线阶段会更复杂。对于并行运行的不同管道,每个管道都将在自己的线程上运行,您可以使用队列将输入传递给它。


推荐阅读