LabVIEW生产者/消费架构

概览

生产者/消费者设计模式基于主/从模式,旨在优化以不同速率运行的多个循环之间的数据共享。生产者/消费者模式用于隔开具有不同数据生成速率和消耗速率的进程。生产者/消费者模式的并行循环分为两类;数据生成循环以及数据消费循环。

本文讨论了生产者/消费者架构的常见用例,并介绍了LabVIEW中使用该技术的相关资源。如要更深入地了解循环之间的信息共享或在LabVIEW中创建生产者/消费者循环的分步讲解指南以及练习,建议学习《LabVIEW Core 2》课程。

内容

为什么使用生产者/消费模式?

生产者/消费者模式可以轻松地同时处理多个进程,同时还能以不同速率迭代。

缓冲通信

当多个进程以不同速度运行时,就适合采用进程间缓冲通信。有了足够大的缓冲区后,生产者循环可以以快于消费者循环的速度运行,而不会丢失数据。
比如,有一个包含两个进程的应用程序,第一个进程负责数据采集,第二个进程将数据传输到网络上。第一个进程的运行速度是第二个进程的三倍。如果使用生产者/消费者设计模式来实现此应用程序,则数据采集进程充当生产者,网络进程充当消费者。当拥有足够大的通信队列(缓存区)时,网络进程便可以访问数据采集循环采集到的大量数据。这种数据缓存能力能够最大程度地减少数据丢失。

对于在使用队列功能时发生的缓冲通信,如果要将其可视化,请参见范例程序:使用生产者/消费者循环移动LabVIEW窗口

数据采集处理

在采集需按顺序处理的多组数据时,通常采用生产者/消费者模式。
假设要编写一个应用程序,该应用程序在接受数据的同时,还要按照接收顺序处理数据。由于这些数据的排队(生产)速度比实际处理(消费)速度高出很多,因此生产者/消费者设计模式最适合此类应用程序。通过这种方法,消费者循环可以按自己的速率处理数据,同时生产者循环也可以让额外的数据排队。

试想一下–如果生产者和消费者都在该应用程序的同一循环中,为了匹配数据处理速度,数据采集速度就会变慢。 这就是按进程、数据采集(生产者)和处理(消费者)对代码进行分解的好处。 

网络通信

网络通信需要两个进程同时以不同的速度运行:第一个进程将不断轮询网络线路并检索数据包,第二个进程将提取第一个进程检索的这些数据包并加以分析。在此范例中,第一个进程充当生产者,因为它向第二个进程提供数据,而第二个进程则充当消费者。这时就非常适合使用生产者/消费者设计模式。并行的生产者循环和消费者循环要同时检索和分析网络外数据,两个循环之间的排队通信可以对检索到的网络数据包进行缓存。这种缓冲在网络通信繁忙时就显得非常重要。借助缓存,数据包的检索和传输速度可以超过分析速度。

队列消息处理

排队消息处理器架构是生产者/消费者架构的一个特殊版本。数据队列用于为生产者/消费者设计模式中的循环之间传递数据。这些队列提供了一个优势,即生产者和消费者循环间的数据缓冲。

建立生产者/消费者

生产者/消费者设计模式由并行循环组成,这些循环分为两类:生产者循环和消费者循环。生产者循环和消费者循环间的通信可以使用队列通道连线来实现。

队列

LabVIEW内置的队列操作VI可在函数选板>>数据通信>>队列操作( Functions>> Data Communication >> Queue Operations)中找到。

队列基于先进/先出理论。在生产者/消费者设计模式中,队列可以在生产者循环和消费者循环之外初始化。生产者循环为消费者循环生成数据,所以会向队列添加数据(将数据添加到队列中称为“入列”)。

消费者循环将从该队列中删除数据(从队列中删除数据称为“出列”)。因为队列基于先进先出原则,所以消费者总是按照生产者向队列添加数据的顺序对数据进行分析。图1显示如何在LabVIEW中创建生产者/消费者设计模式。


图1:生产者/消费者设计模式

注意:图像一段LabVIEW代码,其中包含项目可以LabVIEW代码。使用代码段,单击图像,保存计算机,然后文件拖到LabVIEW上。 


LabVIEW中提供有关于使用队列的范例,可作为应用程序开发的起点。如果要搜索这些范例,可在LabVIEW范例查找器中搜索“队列”(Queue)。

通道

LabVIEW 2016新增了通道连线功能。通道连线可以实现与队列相同的功能。

在队列中,您可以设置队列引用(获取队列)、添加数据(入列)和删除数据(出列),然后关闭队列引用(发布队列);使用通道(Channels)功能,该过程将简化为仅设置数据的Writer和Reader。

有关通道连线和入门模板的更多信息,请参见《LabVIEW帮助文档:使用通道连线在代码的并行部分之间通信数据》

重要说明

在处理生产者/消费者设计模式时,需要注意一些注意事项,例如,队列的使用和同步。

队列使用

问题: 队列被绑定到特定的数据类型。因此,生产者循环中产生的每个不同数据条目都需要放置到不同的队列中。这可能带来一个问题,那就是增加了程序框图的复杂性。
解决方案: 队列可以接受数组和簇等数据类型。每个数据条目都可以放到一个簇中。这样就会掩盖簇数据类型背后的各种数据类型。图1使用通信队列执行簇数据类型。

同步

问题: 由于生产者/消费者设计模式并非基于同步,循环初次执行时并不遵循特定的顺序。 因此,在一个循环之前启动另一个循环可能会导致问题。

解决方案: 可以通过将事件结构添加到生产者/消费者设计模式解决这类同步问题。 图2显示了实现这一功能的模板。 有关同步功能的更多信息,详见“相关链接”部分下方。


2:生产者/消费设计模式使用事件结构

 注意:图像一段LabVIEW代码,其中包含项目可以LabVIEW代码。使用代码段,单击图像,保存计算机,然后文件拖到LabVIEW上。 
 

Was this information helpful?

Yes

No