2011年9月25日,第一稿
9.4 图形化语言设计模式之三——生产者队/消费者(事件)
生产者/消费者设计模式是利用LabVIEW图形化语言中的队列操作函数、While循环、Case结构、事件结构等组合构成。
生产者/消费者设计模式是一种多循环的并行处理结构。生产者循环负责信息的提供,而消费者循环则负责信息的处理。因二者工作在不同的循环内(生产者循环、消费者循环)并采用队列的消息(数据)处理方式,所以不会发生消息(数据)丢失的情况。
本节我们先讨论:生产者/消费者(事件)设计模式。
生产者/消费者设计模式是一种多循环的并行处理结构。生产者循环负责信息的提供,而消费者循环则负责信息的处理。因二者工作在不同的循环内(生产者循环、消费者循环)并采用队列的消息(数据)处理方式,所以不会发生消息(数据)丢失的情况。
本节我们先讨论:生产者/消费者(事件)设计模式。
9.4.1 生产者/消费者结构
在我们此前所接触到的循环结构一般都是单循环结构。比如在数据采集处理中较常见的结构参见下图所示。
在上图所示的例程中,数据在单While循环中被读出、分析、处理。如果分析处理过于复杂可能会导致处理时间过长,将会影响到采集数据的速度。
为了解决这个问题,人们创建了一种被称为:生产者/消费者的结构。其原理示意图参见下图[15]。
为了解决这个问题,人们创建了一种被称为:生产者/消费者的结构。其原理示意图参见下图[15]。
这里利用了两个While循环和队列操作函数等构成生产者/消费者结构。依据前端数据源的数据类型,生产者循环产生数据;而消费者循环负责处理数据。由于每个循环只做自己的事情,所以相互之间并不会发生影响。
生产者循环不产生数据,消费者循环则不运行。实际上,生产者循环不断的产生数据送入缓存器,而消费者循环则从缓存器中不断的读出数据。这里队列起到了重要的作用。
生产者循环不产生数据,消费者循环则不运行。实际上,生产者循环不断的产生数据送入缓存器,而消费者循环则从缓存器中不断的读出数据。这里队列起到了重要的作用。
9.4.2 导出生产者/消费者(事件)设计模式
获得生产者/消费者(事件)的设计模式很简单,在LabVIEW的启动界面选择:
》基于模板的VI...或更多...
》新建
》基于模板
》框架
》设计模式
》生产者/消费者设计模式(事件)
参见下图。
》基于模板的VI...或更多...
》新建
》基于模板
》框架
》设计模式
》生产者/消费者设计模式(事件)
参见下图。
在前面的8.4节中我们曾经谈到过,事件处理方式非常适合GUI的设计,同时我们还建议在事件处理机制上避免使用复杂的、时间较长的事件处理步骤(避免事件产生堆积)。现在我们无需担心这样的情况还会发生,使用生产者/消费者(事件)设计模式可以解决这样的问题。因为它的事件处理方式是在不同的循环下异步进行的。
9.4.3 生产者/消费者设计模式(事件)的图形化代码
鼠标双击上图中的“生产者/消费者设计模式(事件)”我们就可以看到它的图形化代码,参见下图所示。
这样一个带有生产者/消费者事件结构的设计模式就可以响应处理GUI事件,并进行异步处理,并不会产生事件的堆积。
下面我们看一个例子,这个例子表明采用生产者/消费者(事件)结构不会发生数据丢失[22]。
下面我们看一个例子,这个例子表明采用生产者/消费者(事件)结构不会发生数据丢失[22]。
另外的一个例子是利用生产者/消费者(事件)响应键盘输入。该例同样来自于NI开发者社区。
使用生产者/消费者(事件)的另一个例子同样也是来自NI的开发者社区,利用变体数据实现多种数据类型的入队列。
作者:WesP
由于队列函数自身的限制入队列的数据类型是唯一的,也就是说入队列的数据类型必须预先明确定义。我们可以使用变体数据实现入队列数据类型的选择。参见下图。
作者:WesP
由于队列函数自身的限制入队列的数据类型是唯一的,也就是说入队列的数据类型必须预先明确定义。我们可以使用变体数据实现入队列数据类型的选择。参见下图。
对于用户GUI事件处理我们依然可以使用事件—队列状态机的结构。这个例子完全可以在自己的应用程序中使用。事件源由我们根据程序需要来进行设定,参见下面的例子所示。
在学习LabVIEW图形化编程语言中,最重要的学习方法就是模仿(套用),所以善于模仿他人的佳作是我们学习过程的一个捷径。当然,如果你的功力强大对于这些结构略加修改就可以在实际应用中使用。甚至发布你的佳作供他人使用。












