LabVIEW程序设计模式(五)—生产者消费者模式(2)_VI的可重入性(Reentrant Execution)
LabVIEW程序设计模式(五)—生产者消费者模式(3)_LabVIEW程序的动态调用
LabVIEW程序设计模式(五)—生产者/消费者模式(3)_LabVIEW程序的动态调用LabVIEW程序设计2009-05-19 17:11:09 阅读696 评论0 字号:大中小订阅简单而言,动态调用指的是通过程序控制另外一个程序的运行、停止、赋值和获取值等。
LabVIEW提供了多种动态调用的方式,从底层而言是通过VI Server 技术实现的。
图31所示为LabVIEW中的Application Control选板,动态调用所使用的节点都位于这个选板。
当调用一个在硬盘、内存甚至是网络路径上的vi时,首先要使用Open VI Reference以将该VI载入内存并获取VI的“句柄(Reference)”;然后再使用该句柄进行其它的控制操作;最后再关闭该VI的句柄避免内存泄漏,这就完成了一次对VI的调用。
图31 Application Control选板图32是一个动态调用的具体实现代码,首先使用Open VI Reference获取被动态调用VI的Reference(例子中是C:\average.vi);再使用Call By Reference Node 节电动态运行该VI;最后关闭VI的Reference。
在使用Call By Reference Node 时需要事先指定被调用VI的输入输出接口,也就是说这种动态调用的前提是必须知道被调用VI的输入输出接口,否则无法进行动态调用。
图32 VI的动态调用Open VI Reference的路径输入是一个多态的输入口,也可以使用String输入,如图33所示。
此时被调用的VI必须在内存中,且输入的是被调用VI的文件名。
值得一提的是这种“文件名”调用方式在可执行程序中是无法被调用的,因此建议最好采用路径的调用方式。
图33 Open VI Reference的多态性【应用5】本例将使用LabVIEW的动态调用方式实现斐波那契数列(Fibonacci数列)。
labview生产者消费者
生产者/消费者模式(1)_前言statemice的LabVIEW程序设计模式(五)—生产者/消费者模式(1)_前言再次回顾“基本状态机模式”的6个缺点,只剩下第6个缺点无法在上述的“状态机和事件结构的结合模式”中被解决。
(1) 任何时刻只能有一个状态在运行这个问题也许有些多余,但是在实际的应用中往往又是最常见的。
大多数比较复杂的应用至少应该有“菜单”和“采集”两个状态,如果数据采集程序在运行时仍然希望系统能够处理菜单的事件,这是在传统的状态机或者事件结构中无法实现的。
因为无论是状态机结构还是事件结构,都是由一个循环组成的,不同的状态是无法同时被响应和处理的。
解决这个问题的方式也比较简单,LabVIEW本身就是一种多线程的程序设计语言,可以再加一个循环或者另外开一个程序独立运行。
但是这样也会带来一些新的问题,比如:(1) 两个循环(程序)之间如何交换和共享数据。
(2) 两个循环(程序)都有着独立的错误处理系统,它们之间是如何协调的。
(3) 两个循环如何分工呢?应该以哪种方式对状态进行分类以将不同的状态放置在不同的循环(程序)中?(4) 一个程序如何控制另一个程序的运行和停止。
在上面提出的4个问题中,对循环和程序这两个解决方案而言,第(1)~(3)个问题的解决方式是一样的。
只有第(4)个问题是专门针对两个程序而言的,在LabVIEW中这种不同程序之间的相互调用称为“程序的动态调用”。
生产者/消费者模式(2)_VI的可重入性(Reentrant Execution)statemice的LabVIEW程序设计模式(五)—生产者/消费者模式(2)_VI的可重入性(Reentrant Execution)在介绍VI的动态调用之前有必要对LabVIEW在执行VI过程中的规则有个大致的了解。
众所周知,LabVIEW是通过VI的文件名(VI Name)来表示独立的VI的,并不是VI的路径。
因此,LabVIEW不允许具有相同名字的VI同时载入内存中,即使这些VI存储在不同的路径中。
精讲LabVIEW设计模式培训
精讲LabVIEW设计模式培训概述LabVIEW是一种图形化编程语言,用于数据采集、控制、仪器仪表通信、图像处理等领域。
设计模式是一种经过验证的最佳实践方法,用于解决特定问题。
本文将精讲LabVIEW设计模式培训,帮助读者了解LabVIEW设计模式的基本概念和应用。
设计模式的概念设计模式是在软件工程中,根据问题的特点和需求的约束,提供一套解决方案的模式。
它可以提高代码的可读性、可维护性和可扩展性。
设计模式分为三大类:创建型模式、结构型模式和行为型模式。
在LabVIEW中,常用的设计模式包括状态机模式、发布-订阅模式、命令模式等。
状态机模式状态机模式是一种通过定义对象的状态来解决特定问题的设计模式。
在LabVIEW中,状态机模式常被用于处理事件驱动的程序。
它通过不同的状态和状态之间的转换来实现特定功能。
例如,一个简单的状态机模式可以用于控制流程的顺序执行,通过定义不同的状态和状态之间的转换条件,实现不同的程序逻辑。
发布-订阅模式发布-订阅模式是一种实现对象间松耦合的设计模式。
在LabVIEW中,发布-订阅模式被广泛应用于多任务编程和消息传递。
它通过将消息的发布和订阅分离,实现不同模块之间的通信。
例如,一个发布-订阅模式可以用于实现观察者模式,让观察者模块监听某个对象的状态变化。
命令模式命令模式是一种将请求封装为对象,以此来参数化客户端的设计模式。
在LabVIEW中,命令模式常被用于实现撤销和重做功能。
它通过将动作封装成命令对象,实现对动作的参数化和执行。
例如,一个命令模式可以用于实现对仪器的控制,每个命令对象代表一个具体的操作,可以被撤销和重做。
实例讲解下面,我们将通过一个简单的实例来讲解LabVIEW设计模式的应用。
假设我们需要编写一个程序来控制一个自动化实验装置,包括采集数据、处理数据和输出结果。
我们可以使用状态机模式来实现流程的顺序控制,使用发布-订阅模式来实现模块间的通信,使用命令模式来实现对仪器的操作。
精通LabVIEW虚拟仪器程序设计
精通LabVIEW虚拟仪器程序设计LabVIEW是一种图形化编程语言,它广泛应用于虚拟仪器的设计和开发。
精通LabVIEW虚拟仪器程序设计,需要对LabVIEW的基本概念、编程环境、编程技巧以及高级功能有深入的理解和实践。
LabVIEW基础首先,了解LabVIEW的基本概念是至关重要的。
LabVIEW使用图形化编程,与传统的文本编程语言不同,它通过图形化的“块图”来表示程序的逻辑。
LabVIEW的编程元素包括函数、控件、指示器、数组、簇等。
编程环境LabVIEW的编程环境主要由前面板(Front Panel)和块图(Block Diagram)组成。
前面板用于设计用户界面,块图用于编写程序逻辑。
熟悉这些界面元素和环境设置是精通LabVIEW的第一步。
编程技巧1. 结构化编程:使用循环结构、条件结构和事件结构来组织代码,使程序更加模块化和易于维护。
2. 数据流编程:LabVIEW支持数据流编程,这意味着数据的流动决定了程序的执行顺序。
3. 数组和簇:掌握数组和簇的使用,可以有效地处理大量数据和复杂的数据结构。
4. 错误处理:学会使用错误处理结构来增强程序的健壮性。
高级功能1. 多线程:LabVIEW支持多线程编程,可以利用多核处理器的计算能力。
2. 动态调用:使用动态调用可以创建更灵活的程序,适应不同的运行时需求。
3. 信号处理:LabVIEW提供了丰富的信号处理工具,包括滤波器设计、频谱分析等。
4. 仪器控制:LabVIEW可以与多种仪器进行通信,实现自动化测试和数据采集。
实践应用精通LabVIEW不仅仅是理论知识的学习,更重要的是将这些知识应用到实践中。
以下是一些实践应用的建议:1. 项目实践:通过参与实际的LabVIEW项目,可以加深对LabVIEW编程的理解。
2. 案例学习:研究现有的LabVIEW程序,了解其设计思路和实现方法。
3. 社区交流:加入LabVIEW开发者社区,与其他开发者交流经验,获取新的思路和解决方案。
Labview程序设计模式
Labview程序设计模式LabVIEW程序设计模式,这个相对学术化的词语是对一系列用于LabVIEW程序设计结构的归纳和总结。
在建造房子时,需要针对房子的用途设计整个房屋的架构,确保房子在这个架构上的坚固性和可建造性。
写程序时同样如此,不同的应用需要使用不同的程序设计结构。
例如我们在LabVIEW中构建一个用户界面型程序时,往往首先在背面板中加入一个大的while循环以使程序持续运行。
如果需要响应用户界面事件则还需要加入一个Event事件结构。
那么我们是否曾经考虑过以下的这些问题:(1) 应用中是否存在并行响应的情况?如在持续的数据采集过程中,是否需要同时响应单击菜单的事件?(2) 底层获取的数据如何与上层的数据显示部分进行数据交互?(3) 上层的界面如何受底层程序的控制?(4) 同一个循环中采用哪种方式进行数据交换?是局域变量、全局变量、共享变量还是移位寄存器?(5) 程序是否具有可扩展性?(6) 如果程序运行过程中,发生系统错误或者硬件通讯错误,是否会停止运行?待错误排除后是否会继续运行?(7) 如何组织程序中的核心数据结构?是否需要采用面向对象程序设计?(8) 如何记录测试数据并生成报表?如何保存用户配置参数?(9) 如何处理程序运行中的断电情况?重新启动时的继续运行?数据的最低丢失?(10) 如何实现运行过程的采样触发和多点采样的同步?当然,也许只是使用LabVIEW临时地调试或开发某个小的应用,无需考虑上述的问题。
但是,如果使用LabVIEW开发一个典型应用的程序却无法回避这些问题。
因此,有必要对各种程序开发的应用进行归纳和总结,提取它们对应的LabVIEW程序结构中的共性。
此外,针对这些共性研究哪种结构更加适合于应用。
这些结论综合起来就形成了程序设计的模式。
对于初学者而言,理解和掌握程序设计模式往往能起到事半功倍的效果;而对高级用户而言,归纳各种程序设计模式又能够不断完善程序中遇到的问题,并衍生一套符合特定应用的特有的程序设计模式。
5_项目实战——【LabVIEW高级培训讲义】
程序性能分析
Q&A
• 生产者/消费者设计模式
是主从设计模式的一种,它将多个并行循环分为生产数据 和消费数据的两类循环,循环间采用队列方式进行通信,这样当 产生数据的速度比处理数据的速度快时,队列的缓冲作用保证数 据不会丢失。
这种模式对于处理需要较长时间才能完成的用户界面事件 非常有效。
• 队列消息处理器 所有消息或事件按顺序排列,编写相应的子程序框图或分
LabVIEW项目实战
• 程序的设计模式 • 程序的调试技巧 • 多线程程序 • 程序性能优化 • 程序性能分析
• 程序的设计模式 • 程序的调试技巧 • 多线程程序 • 程序性能优化 • 程序性能分析
• 标准状态机模式
构成:一个while循环、一个移位寄存器和一个条件结构。
系统在某一时刻只能处于一个状态,当收到一个输入条件 时,状态机产生一个输出,同时伴随状态的转移。
支代码,然后按排列的顺序处理队列中的消息或事件
构成:带移位寄存器的while循环和放置于循环内的条件结 构。
• 其它 后台程序模式 代理模式 启动界面模式
• 程序的设计模式 • 程序的调试技巧 • 多线程程序 • 程序性能优化 • 程序性能分析
程序的调试技巧
• 建立出错处理机制 • 检查数据的依从关系 • 检查部分代码段对程序的影响 • 子VI的挂起 • 检查端口连线是否正确 • 使用即时帮助窗口 • 检查函数端口的默认值 • 检查是否有没接线的子程序 • 检查未定义数据 • 检查数据溢出 • 检查簇成员的顺序
初始化状态、根据不同动作进入对应状态、最终状态(退 出)
• 主/从设计模式
多循环的模块式结构、适用于多任务的应用程序,更有效 地控制应用程序中各任务的同步执行。
如何使用VI的重入属性知识
如何使用V I的重入属性知识Last revision date: 13 December 2020.2016年04月在 VI Properties -> Execution 中可以选择 VI 的Reentrant Execution属性(中文译为:可重入执行)。
我们在《LabVIEW 程序的内存优化》一文中讨论过,尽量不要把 VI 设置为重入属性,因为这样就多占用了内存,降低了运行效率。
此外,如果不加注意的话,还可能引发多线程不安全的问题。
尽管可重入 VI 在 LabVIEW 中不是必须的,但是在某些情况下使用可重入 VI 可以简化我们的程序。
那么在什么情况下可以使用 Reentrant VI 呢?首先看一下图 1 所示的程序,程序中调用的两个子 VI 是同一个 VI,并且不是可重入的 VI。
LabVIEW 是自动多线程的语言,那么图中的两个子VI会不会同时执行呢。
一定不会的。
如果程序中调用的是两个不同的子 VI,LabVIEW 有可能会同时在不同的线程执行它们,但对于两次调用相同的子 VI,LabVIEW 一定要等一个执行完,再执行另一个。
图1:并行的两个相同子 VI其原因是,LabVIEW 会为每个 VI 都开辟一块内存用于数据存储。
作为子 VI,每次被调用,它的局部变量的数据都是被存在同一地址的。
与 C 语言相对照,在默认情况下,VI 是不可重入的,VI 中所有的局部变量都是静态变量。
如果 LabVIEW 在不同的线程下执行同一 VI,那么两个线程就会同时对这一块数据地址进行读写,就会导致这一块地址内数据的混乱。
为避免此类不安全情况的出现,LabVIEW 必须等待一个子 VI 执行结束,再执行另一个子 VI。
如果需要图1 中的两个子 VI 同时运行,比如子 VI 所做的工作是读取文件这样一类耗时多、但CPU占用不大的操作,则并行执行可以大大提高效率。
这时,就需要把子 VI 设置为可重入了。
LabVIEW之生产者-消费者模式--队列操作
LabVIEW之生产者-消费者模式--队列操作
LabVIEW之生产者/消费者模式--队列操作
本文章主要是对学习LabVIEW 之生产者/消费者模式的学习笔记,其
中涉及到同步控制技术-队列、事件、状态机、生产者-消费者模式,这几种技
术在在本章中都会有侧重点的进行介绍和总结!队列同步技术-操作函数同步控制技术可以实现在多个VI 之间或者同一VI 不同县城之间同步任务和交换数据;在LabVIEW 中提供了同步函数选板,包括通知器、队列、信号量、集
合点、事件、首次调用函数,本文主要关注同步控制技术之队列技术:
队列操作函数:
1 获取队列引用函数
2 “元素入队列”和元素出队列函数
函数作用:将元素入队列和出队列用(没什么好说的!)超时毫秒(-1)端子:如果未连接,默认输入值为-1,表示永不超时,如果队列满,则一直等待直到队列有空位为止;如果连接端子,则新元素等待设定时间后仍无法入队列,则结束本次等待!3 最前端插入元素和有损耗元素入队列函数
函数作用:将元素插入队列,不过插入队列方式有区别;元素入队列、最前端插入元素、有损耗元素入队列三者区别:元素入队列函数采用先入后出次序,而最前端插入元素函数则采用后入先出(FIFO)的原则,类似于堆栈,因此可以使用队列实现堆栈效果,相比数组实现有优势;元素入队列函数如果队列满,则线程等待,直到有空位为止;有损耗元素入队列在这种情况下则会自动删除队列前端元素,并在末端插入元素,可以用于实现缓冲区效果; 4 预览队列元素函数预览队列元素和元素出队列区别:当返回队列前段的元素时,是否删除该元素!5 获取队列状态函数:主要用于判定队列引用是否有
效!。
如何使用VI的重入属性知识
2016年04月在VIProperties->Execution中可以选择VI的ReentrantExecution属性(中文译为:可重入执行)。
我们在《LabVIEW程序的内存优化》一文中讨论过,尽量不要把VI设置为重入属性,因为这样就多占用了内存,降低了运行效率。
此外,如果不加注意的话,还可能引发多线程不安全的问题。
尽管可重入VI在LabVIEW中不是必须的,但是在某些情况下使用可重入VI可以简化我们的程序。
那么在什么情况下可以使用ReentrantVI呢?首先看一下图1所示的程序,程序中调用的两个子VI是同一个VI,并且不是可重入的VI。
LabVIEW是自动多线程的语言,那么图中的两个子VI会不会同时执行呢。
一定不会的。
如果程序中调用的是两个不同的子VI,LabVIEW有可能会同时在不同的线程执行它们,但对于两次调用相同的子VI,LabVIEW一定要等一个执行完,再执行另一个。
图1:并行的两个相同子VI其原因是,LabVIEW会为每个VI都开辟一块内存用于数据存储。
作为子VI,每次被调用,它的局部变量的数据都是被存在同一地址的。
与C语言相对照,在默认情况下,VI是不可重入的,VI中所有的局部变量都是静态变量。
如果LabVIEW在不同的线程下执行同一VI,那么两个线程就会同时对这一块数据地址进行读写,就会导致这一块地址内数据的混乱。
为避免此类不安全情况的出现,LabVIEW必须等待一个子VI执行结束,再执行另一个子VI。
如果需要图1中的两个子VI同时运行,比如子VI所做的工作是读取文件这样一类耗时多、但CPU占用不大的操作,则并行执行可以大大提高效率。
这时,就需要把子VI设置为可重入了。
LabVIEW在不同的地方调用一个可重入VI时,会给它另外分配一个独立的数据地址空间。
这样就做到了线程安全。
在两个线程执行的子VI使用两份在不同的地址存储的数据,也就不会造成混乱。
但是千万要注意,这个“在不同的地方”调用:不可重入的VI的局部变量与C语言中非静态变量的含义是不同的。
LabVIEW学习日记
1.1 生产者/消费者设计模式概念生产者/消费者设计模式包括多个并行循环,每个循环以不同的速率执行任务。
一个循环作为生产数据的循环,其他循环作为消费数据的循环。
生产数据的循环控制所有消费数据的循环,并且使用通信技术与它们进行通信。
2011.9.171.生成EXE文件步骤:点击“工具”——>点击“通过VI生成应用程序(EXE)…”——>弹出下面对话框选择存放目录——>点击“继续”在该对话框中选中左面的“信息”点击右边的“目标目录”更改目录点击“当前目录”,该对话筐还有其他设置。
点击“生成”出现如下对话框,就可以在对应位置找到*.exe文件。
2.电压电流采集的实现前面板如下图:程序框图如下:主要用到了labview功能模块中的DAQmx-数据采集中的几个模块:1、DQAmx创建任务:这个函数用来创建一个DAQmx数据采集任务2、DAQmx创建通道(AI-电压-基本):这个函数是新建虚拟通道函数,对最大值、最小值、单位、通道等参数进行设置。
3、DAQmx创建通道(AI-电流-基本):同DAQmx创建通道(AI-电压-基本)4、DAQmx定时(采样时钟):主要是对采样频率进行设置。
连续采样时的缓冲区大小。
5、DAQmx读取(模拟2D DBL N通道N采样):是一个读数据函数,用来从指定的通道或任务读取数据的数据。
这里用到循环结构实现连续采集。
6、DAQmx清除任务:VI将终止该任务,并且不能使用该任务的资源。
注:1、一个任务可以有多个通道如可以同时采集电压和电流等,但不能选择不同类型如模拟输入、数值输入。
2、注意电压电流的最大值和最小值范围。
电压:-10v~10v,电流:-0.01A~0.01A。
绘制VI曲线程序框图:在前面程序框图基础上的DAQmx读取函数的数据输出端,将二维数据(行代表通道这里就是电压,电流)拆分为两个一维,绘制成VI 曲线。
1、调用索引数组函数行数,提取电压和电流数据。
第2章 LabVIEW程序设计模式
23
使用数组处理消息队列
在建立消息队列之前首先要确定程序的状 态,“初始化”状态是必不可少的,它用以复 位前面板控件、中间变量值、寄存器值和打开 扫描仪器等;“等待”状态,在该状态下程序 一直探测前面板三个按钮的动作;“退出”状 态用于销毁空间,关闭扫描仪器等;此外,还 需要“扫描区域A”、“扫描区域B”、“扫描 区域C”和“扫描区域D”分别控制各个不同的 扫描区域。
2
LabVIEW程序设计模式
源于虚拟仪器技术的LabVIEW程序设计语言, 从被创建开始就是面向测量和应用的,并且绝 大多数采用LabVIEW开发的应用程序都同测控仪 器等硬件设备紧密结合。虽然这些设备的类型 和规模各不相同,应用领域的差异也很大,但 从测量和控制过程的基本步骤来看,绝大多数 的LabVIEW程序的基本框架是有章可循的,具有 一定的模式特征。
例2 使用改进的顺序型状态机计时
16
测试流程型状态机
顺序型状态机还有一个缺点:不便于阅读 和修改程序,Case结构的子框图列表中显示的 是数值,不具有任何的实际意义。所以需要找 到一种方式,不仅能够保证Case结构的正常运 行,还要能够很方便地识别Case结构中各个子 框图的功能。 使用枚举型常量代替数值型常量控制状态 机运行,也就是我们提出的测试流程型状态机, 正好能满足我们的要求。
24
使用数组处理消息队列
建立消 息队列
移出消息 队列
加入消 息队列
扫描例程—初始化状态
25
使用数组处理消息队列
扫描例程——等待状态
26
使用数组处理消息队列
一旦用户单击前面板的按钮,这个信息将会 被系统探知,并执行相应的消息处理函数,如 Case子框图标识为“1”、“1”和“3”的源代 码。当没有搜索到任何“真”值时,便将“等 待”状态加入消息队列,以便不断探测消息队 列中的值,维持循环的运行。当搜索到“0”~ “2”时,将相应需要执行的状态序列加入消息 队列。运行完各个扫描区域的代码后,程序应 该继续回到“等待”状态。
labview主/从设计模式和生产者/消费者设计模式
5.2LabVIEW设计模式——主/从设计模式和生产者/消费者设计模式在上一节中曾经谈到过,NI LabVIEW中提供了六种最基本的设计模式。
本节首先介绍其中的两种:主/从设计模式与生产者/消费者设计模式(Master/Slave design pattern and Producer/Consumer design pattern)。
这是由于这两种设计模式在结构上极为相似(使用的内置函数不同),所以我们在这里将一起来讨论(基本结构参见图5.2-1、图5.2-2)。
图5.2-1主/从设计模式图5.2-2生产者/消费者设计模式5.2.1主/从设计模式(Master/Slave design pattern)与主/从设计模式的相关内置函数(Notifier_通知)参见下图所示。
图5.2.1-1主/从设计模式内置函数(通知)关于这些内置函数的定义和使用方法请参考LabVIEW Help文件,这里就不再进行讨论了。
对于绝大多数LabVIEW的学习者来讲,仅仅依据这些主/从操作提供的内置函数(通知),即便是借助于帮助文件也很难理解和设计出正确的应用程序代码或基本架构。
因为这些内置函数的内部程序代码是不对外开放的、不公开的,所以我们也就很难理解的更准确或更全面。
那么如何正确的使用它们呢?通常有两个最简单、最直接的方法可以解决这个问题:一是,查看NI给出的设计模式或例程;二是,查看其它使用者所提供的实用例程。
其实,这里也再次间接的告诉大家,更多查看和理解其它LabVIEW开好者所提供的实用例程是学习LabVIEW的最好方法之一。
通过图5.2-1,就可以初略地领会到NI基于数据流的图形化代码主/从设计模式的表达形式或架构。
从图5.2-1中,可以看到主/从设计模式的基本构成是:包括了两个While循环(上面为主循环、下面的为从循环)和若干个“通知”内置函数(Notifier)构成。
主循环中的Case结构用来确定是否向从循环发出通知。
labview生产者消费者基础知识
燕山大学课程设计说明书题目:LABVIEW程序设计模式——生产者/消费者学院(系):电气工程学院年级专业:生物医学工程 1班学号: ************学生姓名:***指导教师:**燕山大学课程设计(论文)任务书院(系):电气工程学院基层教学单位:生物医学工程系说明:此表一式四份,学生、指导教师、基层教学单位、系部各一份目录第一章同步VI和函数 (1)1.1队列 (1)1.2通知器 (2)1.3集合点 (4)1.4信号量 (6)1.5事件发生 (8)第二章生产者消费者 (10)2.1状态机 (10)2.2事件结构 (11)2.3生产者消费者 (12)2.3.1组成与结构 (12)2.3.2分类 (12)2.3.3举例说明 (14)第三章并行编程 (18)3.1任务化并行 (18)3.2数据并行化 (18)3.3流水线 (21)设计小结 (24)参考文献: (25)第一章同步VI和函数1.1队列概念:队列操作函数用于创建在同一程序框图的不同部分间或不同VI间进行数据通信的队列。
队列操作函数可缓冲数据。
应用举例:队列基础VI前面板注释:上面的波形是随机产生的数据波形,“入队列速度”可以调节随机数产生的速度;下面的波形是通过队列读取随机波形的数据而生成的波形,“出队列速度”可以调节其读取队列中数据的速度。
“队列中元素”是下面波形未来得及读的数据,“队列大小”可以调节队列的容量。
程序框图注释:1)创建Data队列,设置数据类型和大小。
2)左上方循环-生成并传递数据至“元素入队列”函数。
通过“等待(ms)”函数控制循环速度,选择等待100ms或500ms。
“释放队列引用”执行时停止循环。
此时队列已不存在,进行元素出队列操作将产生错误。
3)下方循环-返回队列中元素的个数,并通过属性节点将数据传递至波形图表。
如按下停止按钮或“获取队列引用”函数发生错误,循环将停止。
循环停止时,将调用“释放队列引用”函数,终止其它两个循环,同时报告“获取队列引用”函数可能发生的错误。
LabVIEW实现递归与可重入VI
可以选择真时继续()。
计数接线端:表示已经完成的循环次数,该计数从0开始。
在本例中,如果当产生的第13个点值超过0.9时,计数器值为12。
结构隧道: 当需要将循环中的数据传入或者传出时,我们使用隧道的方式(这一点将在后面详细介绍)。
2. For 循环For 循环常用于已知代码循环次数的情况,比如数组的操作。
下面是For循环的流程图:2.1 For 循环的流程图我们通过以下的例子来具体介绍以下For 循环: 如图 2.2,使用For 循环产生一个3×4的二维随机数组。
(该程序见附件Generate array.vi )图2.2 For 循环产生3×4的二维随机数组递归与可重用VI1. VI 递归LabVIEW 中使用递归调用不是很方便。
并且递归并不是编程必须程序结构,任何需要使用递归调用的地方,都可以用循环结构来代替。
但是在某些情况下,使用递归调用的确可以大大简化程序代码,对缩短编程时间、提高程序可读性都非常有帮助,所以学习一下递归的实现方法还是有好处的。
在LabVIEW 2009以前的版本中,只能通过VI 服务器动态调用VI 的方法来实现递归调用。
在LabVIEW 2009之后,在设置好VI 的可重入特性后,可以直接递归调用VI 。
目前在32位计算机上,为避免大量内存泄露,递归调用次数不能超过1,5000次。
2. 递归调用实例在此,我们要实现的例子是阶乘运算。
如果用for 循环结构,很容易的用下面的程序实现该功能(见图1)。
用递归调用,需要先指定VI 连线板与前面板对象的关联,特别需要注意的是指定VI 的“执行”属性为“可重入执行”和“在实例见共享副本”。
具体步骤是:1. 在VI 前面板分别放置数值输入控件和数值显示控件,标签分别为n 和n!。
2. 编辑VI 的图标如下图2所示:3. 分别指定VI 连线板的输入与输出。
4. 在文件菜单下,选择VI 属性中的执行类别,选择“可重入执行”和“在实例见共享副本”。
LABVIEW开发技巧
LABVIEW开发技巧写好LabVIEW程序不可不知的利器(一):模块化功能VI对于一般的初学者,无论是否有程序基础,LabVIEW是个相当容易入门的程序语言。
因为LabVIEW图形化以及资料流的概念,相对于文字叙述的程序语言较容易理解。
也正因如此,虽然初学者在刚开始接触LabVIEW时,可以非常快速的使用内建的Function或VI来写一些小程序,但一遇到程序需要增加较多功能时,程序往往越写越庞大而复杂,程序码杂乱无章,图形化此时反而没有得到较多的好处。
这也是导致一般人对于LabVIEW的印象是很容易上手,但只能写一些小程序。
其实只要善用SubVI将程序功能模块化,以及选择适当的程序架构,无论多复杂的程序也能轻松地完成。
上图是一个红绿灯的小程序,其功能是一开始红灯先亮2秒,接着换黄灯亮1秒,最后再换绿灯亮3秒。
最直觉的写法当然就是用Sequence轮流让三个灯亮起且分别等待不同的时间,而其中因为要将前一个灯关掉,所以会用到LocalVariable,如下图。
这种直觉式的写法非常简单,可以在短时间内完成程序,初学者也较常使用这种思维来写程序。
但这样的写法存在着一些缺陷,例如当使用者按下Stop后,需等待程序完整跑完一个循环才会停止,而不能实时将程序停止。
这也是使用Sequence当作程序架构的缺点,当Sequence执行过程中发生Error时,并没有办法直接跳出Sequence 来解决Error或是将程序停止。
而且程序里面大部分的工作是WaitTime,如果要让这个程序在同个循环中执行其他功能会非常难写,因为循环的更新时间是6秒。
在LabVIEW里面,建议不要将循环时间设的太长或太短。
时间太长的话,按键的反应会非常不灵敏;太短的话,则会比较占CPU资源。
一般只要人眼无法辨识人机界面的更新即可,通常将循环更新时间设为约100ms。
除非程序码执行的时间超过100ms(通常是卡在硬件通讯时间),可以再设长一点。
LabVIEW 编程模式
LabVIEW 软件工程方法一、LabVIEW 编程模式编程模式,是指一些固定有用的程序结构模式,是编程经验的总结和提炼,并经过了多次成功验证。
使用被广泛接受的编程模式设计出的应用程序,很容易被其他开发人员读懂或修改,也是软件重用的重要基础。
常见的LabVIEW编程模式主要有状态机模式(Staste Machine)、队列消息模式(QueuedMessage Handler)、用户界面事件模式(UI Event Loop)、主/ 从结构模式(Master/Slave)和生产者/ 消费者模式(Producer/Consumer)等。
这5 种模式应用的非常普遍,并且在LabVIEW中,也可以较为方便地实现这5 种编程模式。
状态机模式是LabVIEW 程序设计中最常用的设计模式之一。
它可以用来清晰地实现任何以状态图描述的算法,它的每一种状态对应一种相应的操作。
状态机常用在决策算法中。
例如诊断、监测和控制等。
图1 所示为LabVIEW状态机程序框图的主框架。
由图1 可知,LabVIEW 标准状态机主要由一个While 循环和一个Case 结构构成,并利用移位寄存器来实现状态的跳转。
为了方便编程,可采用Typedef 来实现状态枚举值,这样当需要修改程序状态时,只需要改变Typedef 就可以改变所有的枚举变量。
图1 标准状态机程序框图队列消息模式同状态机模式有些类似,这种模式通常被用于需要特定处理顺序的场合。
用户界面事件模式采用事件结构来响应用户的操作,这种交互方式可以处理诸如鼠标移动、键盘操作、值改变等事件。
由于事件捕获的方式是采用中断方式实现的,因而避免了轮询导致的CPU 资源的浪费,而且会自动产生事件队列,避免了事件的丢失。
但由于它必须执行完前一个事件后才能执行下一个事件,因此任何一个事件结构的执行时间必须尽量地短,以避免用户的误操作。
主/ 从结构模式通常应用于同时有两个或多个以不同频率运行的循环并且循环之间存在有信息交换时的场合。
精讲LabVIEW设计模式(XXXX)
天津大学精仪学院
21
消息源
消息处理过程
建立消息队列 加入消息
探测消息
No
EXIT?
Yes 销毁消息队列
删除消息
接收消息 执行代码
天津大学精仪学院
22
队列建立方式 队列函数和数组
天津大学精仪学院
23
队列函数 最常用的 4个函数
43
生产者/消费者
“我需要可以同时间执行的两个过程,并且需保 证它们不会互相影响执行速度。”
天津大学精仪学院
44
生产者/消费者
全局变量、局域变量或共享变量的每次复制都是原始数 据的一个副本,占据了大量的空间。实际上只需要使用 一部分缓冲区作为数据存储的中间部分,这需要借助队 列技术。
数据流入
存储单元
• 事件结构是如何工作的?
– 当面板上事件发生时才被唤醒 – 自动执行相应事件框图内的事件代码 – 当处理完成相应事件后便结束,并不一直循环等
待
天津大学精仪学院
31
为什么要使用事件结构 ?
• 用更简单的事件处理替代原来的查询循环 • 最小化 CPU 的使用 • 不会遗漏用户界面交互事件 • 可检测更多的交互事件 • 编程生成您自己的事件
3、Deadline:用于指定完成一个循环的时间限定,如未在 指定的时间内完成,则左端数据节点Finished Late?[i-1]返 回真。默认值-1表示Deadline由Period决定。
4、如何处理某次循环使用的时间大于设定的周期? 是否丢弃丢失的了的循环?是否保持原始相位?
天津大学精仪学院
63
天津大学精仪学院
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
LabVIEW程序设计模式(五)—生产者/消费者模式(2)_VI的可重入性(Reentrant Execution)
LabVIEW程序设计2009-05-19 17:06:34 阅读698 评论0 字号:大中小订阅
在介绍VI的动态调用之前有必要对LabVIEW在执行VI过程中的规则有个大致的了解。
众所周知,LabVIEW是通过VI的文件名(VI Name)来表示独立的VI的,并不是VI的路径。
因此,LabVIEW不允许具有相同名字的VI同时载入内存中,即使这些VI存储在不同的路径中。
在前面曾经提到,LabVIEW本身就是一种多线程设计的语言。
那么当同一背面板中放置两个VI的实例时代码应该如何执行呢?在图29中,右侧是测试VI运行的时间,左侧是Wait.vi的具体实现代码,仅仅是等待一定的秒数。
那么在右侧的VI中,输出的Time是多少呢?是3秒还是2秒?
图29 Reentrant Execution
打开VI的Highlight调试工具,可以看出两个Wait.vi实例的调用并不是同时执行的,而是依次按顺序执行的,至于哪一个实例先执行是不确定的。
这是由于LabVIEW本身是并行设计的,从理论上而言,两个VI的实例是同步执行的,但是如果两个Wait.vi实例同时执行必定会产生参数赋值紊乱,因为LabVIEW只允许内存中存在一个名称的VI。
因此,此时Time的输出结果是3秒。
如果在实际使用中需要这样的应用该如何解决呢?LabVIEW提供了VI的可重入技术,打开Wait.vi,单击<Ctrl+I>按键,选择图30所示的Reentrant execution 选项。
此时再次运行Time的输出结果是2秒。
从Highlight的运行过程来看,两个Wait.vi实例是同时执行的,因此总的运行时间就是1秒。
图30 VI Properties
事实上,LabVIEW的可重入技术相当于在原有VI的基础上产生了一个相同的副本,打开Wait.vi从标题栏可以看出VI的名称为Wait.vi:1(clone)。
同理这是由于LabVIEW中不允许内存中的VI存在同名,VI的可重入技术相当于产生了与原VI具有同样功能的新VI并且修改了该VI的命名。
在实际应用中,需要根据情况决定是否设置VI的可重入属性,灵活使用。
并不是需要将所有的VI都设置为可重入,那将占据大量的内存资源。
评论这张
转发至微博
0人 | 分享到:
阅读(698)| 评论(0)| 引用(1) |举报。