📜  流水线的实现

📅  最后修改于: 2020-12-13 05:19:03             🧑  作者: Mango

流水线的实施

为了实现管道以评估给定用户查询的多个操作,我们需要构造一个简单而复杂的操作,该操作合并给定查询的多个操作,这将实现一个管道。但是,这种方法对于某些经常发生的情况是可行和有效的。

系统可以使用以下任何一种方式来执行管道:

需求驱动管道

在需求驱动的管道中,系统反复从操作(在管道的顶部)发出元组请求。每当该操作获得对元组的系统请求时,最初,它都会计算将要返回的下一个元组,然后,此操作将返回所请求的元组。每次从系统接收到任何元组请求时,该操作都会重复相同的过程。如果操作的输入没有流水线,那么我们仅根据输入关系计算下一个返回的元组。但是,系统会跟踪到目前为止已返回的所有元组。但是,如果存在一些流水线输入,该操作也会从其流水线输入中请求元组。从流水线输入中接收元组后,该操作将其用于计算其输出或结果的元组,然后将其传递给上级的父级。因此,在需求驱动的流水线中,流水线是根据系统生成的元组的需求或要求来实现的。

实施需求驱动的管道

在需求驱动的管道中,它将每个操作实现为迭代器。迭代器提供了三个基本功能来实现需求驱动的管道。函数是open(),next()和close()。这些功能的工作方式如下:

  • 调用open()函数,对next()的每次调用都会返回下一个元组作为操作的输出。
  • 反过来,该操作的实现在其输入上调用open()和next()函数,以便在需要时可以容易地使用输入元组。
  • 满足要求后,close()函数告诉迭代器不再有元组要求。
  • 同样,在调用过程之间,迭代器保持其执行状态。结果,连续的next()函数接收连续结果的元组。

生产者驱动的管道

生产者驱动的管道不同于需求驱动的管道。在生产者驱动的管道中,操作不会等待产生元组的系统请求。相反,这些操作渴望生成这样的元组。在生产者驱动的管道中,它将每个操作建模为系统内的单独线程或进程。在这里,系统从其流水线输入中获取元组流,并最终为其输出生成或产生元组流。生产者驱动的管道遵循这种方法。

实施生产者驱动的管道

生产者驱动管道的实现方式不同于需求驱动管道。实施过程按以下步骤描述:

  • 对于每对相邻的操作,系统都会构造一个缓冲区,该缓冲区保存从一个操作传递到下一个操作的元组。
  • 创建缓冲区后,将同时执行与不同操作相对应的进程。
  • 流水线底部出现的所有那些操作会不断产生输出元组,并将它们放入输出缓冲区,直到缓冲区变满。
  • 一旦操作使用来自流水线输入的元组,它将从其输入缓冲区中删除该元组。
  • 如果输出缓冲区已满,则操作将等待,直到缓冲区为更多元组创建更多空间。发生什么情况,指定操作的父操作负责从缓冲区中删除元组。因此,实际上,该操作等待其父操作执行此操作。
  • 因此,当缓冲区再次创建更多空间时,该操作将重新开始其元组生成,并继续进行直到缓冲区再次变满。
  • 该操作重复此过程,直到生成所有输出元组。

注意:如果输入缓冲区为空,输出缓冲区已满,或者需要更多输入元组以生成更多输出元组,则系统有必要切换操作。

生产者驱动管道和需求驱动管道之间的区别

需求驱动管道和生产者驱动管道之间存在以下差异点:

Demand-driven Pipeline Producer-driven Pipeline
It is similar to pulling data up from the top of an operation tree. It is similar to pushing data up from the below of an operation tree.
Tuples are generated in a lazy manner. Tuples are eagerly generated.
It is easy to implement. It is not so easy to implement a producer-driven pipeline.
It is most commonly used for evaluating an expression. It is typical so rarely used in the systems. But, it is good for systems such as parallel processing systems.