【问题标题】:Simple pipeline architecture简单的流水线架构
【发布时间】:2022-11-18 00:09:07
【问题描述】:

我试图理解以下answer

例如,您可能有一个 Source 接口和一个 Sink 接口 - 并且 一个同时实现 Source 和 Sink 的 Filter 抽象类 作为实现 Source 和 Sink 的 Pipe 类,只是通过 数据直接通过。这只是命名和命名的众多方法之一 组织这样一个框架。

我确实多次阅读该段,但我认为我错过了这里的全部要点。有人可以给我一个上面的简单 C++ 实现吗?

这是我目前的状态:

#include <cstdio>
#include <string>

class Source {
public:
  virtual std::string readsome() = 0;
};

class Sink {
public:
  virtual void writesome(std::string const &s) = 0;
};

class Filter : public Source, public Sink {};
class Pipe : public Source, public Sink {};

class Stdin : public Source {
public:
  std::string readsome() {
    char buf[4096];
    size_t nread = fread(buf, 1, sizeof buf, stdin);
    return std::string(buf, nread);
  }
};

class Stdout : public Sink {
public:
  void writesome(std::string const &s) {
    fwrite(s.c_str(), 1, s.size(), stdout);
  }
};

class Tr : public Filter {
  const char From;
  const char To;

public:
  Tr(char from, char to) : From(from), To(to) {}
  std::string readsome() { ... }
  void writesome(std::string const &s) { ... }
};

我如何连接StdinTrStdout?典型的 main 功能表示赞赏。

【问题讨论】:

  • 你的问题到底是什么?看起来你已经掌握了 C++ 实现位,所以......你是在问如何使用它吗?为什么需要这种架构?
  • 你能根据上面的内容发布一个典型的main函数吗?
  • 答案并没有说要使用readsomewritesome 函数。它说基本上要自己设计所有这些东西。
  • 实现过滤图的一种方法是只要readsome只要writesome(两种不同的方式,具体取决于哪个方向对您来说更方便)。然后你就可以调用最后一个过滤器的readsome或第一个过滤器的writesome

标签: c++ design-patterns stream pipeline


【解决方案1】:

您快完成了,但是您忘记了将组件链接在一起。

每一个Source都需要知道它连接的是什么Sink,我们需要稍微改变一下readsome看看能不能有进展。

class Source {
public:
  void setSink(Sink *s) { sink = s; }
  virtual std::optional<std::string> readsome() = 0;
  
  void process() {
    auto item = readsome();
    if (item && sink) {
      sink->writesome(*item);
    }
  }
private:
  Sink *sink;
};

你的main 会是这样的:

Stdin in;
Pipe pipe;
Tr tr;
Stdout out;

in.setSink(&pipe);
pipe.setSink(&tr);
tr.setSink(&out);

while (true) {
  in.process();
}

当然,这不是生产级代码。对于初学者,您可以将所有内容与 shared_ptrs 联系在一起。其次,您需要同时在所有源上调用 process(),这要么需要线程和它带来的所有乐趣,要么需要一个非阻塞的 poll 方法,它首先查看源是否可以产生任何东西。

【讨论】:

  • “每个 Source 都需要知道它连接的是什么 Sink”——就是这样基于推送管道。在基于拉动管道,Sink 从 Source 拉取,因此依赖关系被反转。然后每个 Sink 都需要知道它连接到什么 Source。
  • AFAIK,这与原来的设计不同 [...]and a Filter abstract class that implements both Source and Sink, as well as a Pipe class that implements both Source and Sink and just passes the data straight through
猜你喜欢
  • 2011-09-17
  • 1970-01-01
  • 1970-01-01
  • 2014-01-05
  • 1970-01-01
  • 1970-01-01
  • 2016-06-21
  • 2015-09-25
  • 2011-10-18
相关资源
最近更新 更多