2011年9月5日,第二稿
8.3 LabVIEW图形化语言编程范式之一——过程化编程
我们已经知道:过程化编程要求程序员必须要知道程序要完成什么,并且告诉计算机如何来进行所需的计算工作,包括每个细节操作。简言之,就是将计算机看作一个善始善终服从命令的装置。
作为图形化语言的实践者,现阶段可能已经完成了许多图形化代码的程序设计工作,面对那些已经完成的程序设计,大家可能根本无法感觉到我们在设计中采用了什么样的编程范式。那么图形化语言如何实现过程化编程的呢?
作为图形化语言的实践者,现阶段可能已经完成了许多图形化代码的程序设计工作,面对那些已经完成的程序设计,大家可能根本无法感觉到我们在设计中采用了什么样的编程范式。那么图形化语言如何实现过程化编程的呢?
8.3.1 数据流编程思想导致过程化编程
其实,回顾我们前面的许多内容,我们不难发现:基于数据流编程思想的图形化编程语言中,最基本、最广泛使用的编程范式应该就是过程化编程范式。也就是说:过程化编程是LabVIEW图形化语言中最主要、最基本的编程范式。
这一点,对于已经学习过和使用过这种编程语言的朋友们来讲,我深信,应该是非常好理解的。
在基于数据流图形化语言的编程思想中,我们所强调的数据依赖性和充分利用公共线程必将导致其程序结构都是基于过程化的。
所以采用过程化编程范式是图形化语言最基本、最显著的特征。也是我们必须自觉、不自觉采用的基本编程方式。
特别是在仪器控制和数据采集过程中,由于图形化语言的自身的点,这种过程化编程范式显得更自然、更容易理解。
值得注意的是:基于数据流的过程化编程思想是图形化语言的核心编程思想,也是图形化语言的基本编程范式。程序结构只能控制程序的执行方向,在程序执行方向已经确定的情况下,图形化代码所遵循的数据流还是以过程化的方式来体现。比如Case结构,在逻辑关系确定的情况下所执行的程序代码还是基于过程化的。事件结构亦如此。
这一点,对于已经学习过和使用过这种编程语言的朋友们来讲,我深信,应该是非常好理解的。
在基于数据流图形化语言的编程思想中,我们所强调的数据依赖性和充分利用公共线程必将导致其程序结构都是基于过程化的。
所以采用过程化编程范式是图形化语言最基本、最显著的特征。也是我们必须自觉、不自觉采用的基本编程方式。
特别是在仪器控制和数据采集过程中,由于图形化语言的自身的点,这种过程化编程范式显得更自然、更容易理解。
值得注意的是:基于数据流的过程化编程思想是图形化语言的核心编程思想,也是图形化语言的基本编程范式。程序结构只能控制程序的执行方向,在程序执行方向已经确定的情况下,图形化代码所遵循的数据流还是以过程化的方式来体现。比如Case结构,在逻辑关系确定的情况下所执行的程序代码还是基于过程化的。事件结构亦如此。
8.3.2 图形化语言中过程化编程的主要特点
毋庸置疑,对于图形化程序设计中,只要你贯彻数据流的编程思想,程序的执行自然都是基于过程化处理的。那么这种过程化编程方式有何其它特殊性呢?
自上而下或自下而上的编程方式
基于文本的过程化编程语言,在程序设计中强调“自上而下”的设计方式。而图形化的语言的过程化编程即可以采用“自上而下”的设计方法,也可以采用“自下而上”的设计方法,当然还可以同时采用这两种设计方法同时进行设计。这些仅仅取决于问题的表述和你的设计习惯。
比如在通用应用程序设计时,我们常采用事件驱动机制或状态机来控制程序的运行。开始时我们并不需要为每个状态都填写代码,只要状态运行机制正确就可以。确定状态运行正确后,我们开始对不同状态撰写程序代码。甚至我们可以先写这部分代码,或者将这些代码分配给多人先分别撰写。
又如在测试应用程序设计时,我们可以先设计、实现基本的测试、分析功能,当这部分工作在验证正常后在开始设计其它的部分,如前面板等。实际上,我们往往习惯于先对涉及到硬件部分(数据采集、仪器控制等)的程序进行整体设计(包括仿真试验),最后综合设计完成其它的部分。
图形化语言的这种设计方式增加了程序设计的灵活性。
模块化设计
过程化编程的关键是将待解问题分解为可以实现的程序模块。在图形化语言中,模块是以子vi的形式出现的,每个子vi处理一个或多个任务。充分利用子vi的设计,实现程序代码的直观可读性和简洁性。
模块化设计子vi是一个非常好的选择,考虑到vi的可重复使用,采用通用式设计是一个有效的解决方案。比如:我们有许多NI的数据采集硬件产品,实际上在做数据采集时可能会根据测试任务选择不同的硬件。事先,我们可以设计一个标准的vi,实现对不同硬件的通道配置。这是一个有效的模块化设计的解决方案。由于NI DAQ产品的通道配置与总线(PCI、PXI、USB、cDAQ)无关,所以它适用于大多数硬件配置。
实现的方法其实很简单,一个枚举常量、一个Case结构外加不同硬件的配置代码。参见下图。
自上而下或自下而上的编程方式
基于文本的过程化编程语言,在程序设计中强调“自上而下”的设计方式。而图形化的语言的过程化编程即可以采用“自上而下”的设计方法,也可以采用“自下而上”的设计方法,当然还可以同时采用这两种设计方法同时进行设计。这些仅仅取决于问题的表述和你的设计习惯。
比如在通用应用程序设计时,我们常采用事件驱动机制或状态机来控制程序的运行。开始时我们并不需要为每个状态都填写代码,只要状态运行机制正确就可以。确定状态运行正确后,我们开始对不同状态撰写程序代码。甚至我们可以先写这部分代码,或者将这些代码分配给多人先分别撰写。
又如在测试应用程序设计时,我们可以先设计、实现基本的测试、分析功能,当这部分工作在验证正常后在开始设计其它的部分,如前面板等。实际上,我们往往习惯于先对涉及到硬件部分(数据采集、仪器控制等)的程序进行整体设计(包括仿真试验),最后综合设计完成其它的部分。
图形化语言的这种设计方式增加了程序设计的灵活性。
模块化设计
过程化编程的关键是将待解问题分解为可以实现的程序模块。在图形化语言中,模块是以子vi的形式出现的,每个子vi处理一个或多个任务。充分利用子vi的设计,实现程序代码的直观可读性和简洁性。
模块化设计子vi是一个非常好的选择,考虑到vi的可重复使用,采用通用式设计是一个有效的解决方案。比如:我们有许多NI的数据采集硬件产品,实际上在做数据采集时可能会根据测试任务选择不同的硬件。事先,我们可以设计一个标准的vi,实现对不同硬件的通道配置。这是一个有效的模块化设计的解决方案。由于NI DAQ产品的通道配置与总线(PCI、PXI、USB、cDAQ)无关,所以它适用于大多数硬件配置。
实现的方法其实很简单,一个枚举常量、一个Case结构外加不同硬件的配置代码。参见下图。
这种采用模块化的设计方法的最大好处是增加新的硬件很方便、很灵活,实现起来仅仅需要添加一个枚举常数和Case结构中新硬件的配置代码。
这里还似乎存在一个问题,我们针对不同的硬件设计了不同的配置代码,目的是用模块化的设计方法提高vi的可重用性。实际上,在程序运行中我们仅仅用到了一种硬件的配置代码,也就是由枚举常数所定义的那个Case结构中的硬件,其它Case结构中的硬件配置代码根本没有使用到。这是不是显得有些浪费系统资源,比如内存等。
其实我们根本没必要担心这点,在LabVIEW2010中的编译器对此做了优化处理,在所生成的可执行代码中会去掉了多余的Case结构中根本没有用到的硬件配置代码,近而提高了程序的执行效率。并且,编译本身并不会破坏vi的源代码。
这里请注意,LabVIEW2010的这个新特性是利用增加编译的时间来换得程序执行时间的降低,从而提高了编译后程序执行代码的执行速度。
自动多线程处理
虽然,图形化语言是基于过程化运行机制的。但是,需要注意的是:图形化语言是自动多线程处理的。如果程序设计不当,比如图形化代码随意放置,可能会导致自动多线程运行甚至可能会干扰程序设计的初衷。
这里还似乎存在一个问题,我们针对不同的硬件设计了不同的配置代码,目的是用模块化的设计方法提高vi的可重用性。实际上,在程序运行中我们仅仅用到了一种硬件的配置代码,也就是由枚举常数所定义的那个Case结构中的硬件,其它Case结构中的硬件配置代码根本没有使用到。这是不是显得有些浪费系统资源,比如内存等。
其实我们根本没必要担心这点,在LabVIEW2010中的编译器对此做了优化处理,在所生成的可执行代码中会去掉了多余的Case结构中根本没有用到的硬件配置代码,近而提高了程序的执行效率。并且,编译本身并不会破坏vi的源代码。
这里请注意,LabVIEW2010的这个新特性是利用增加编译的时间来换得程序执行时间的降低,从而提高了编译后程序执行代码的执行速度。
自动多线程处理
虽然,图形化语言是基于过程化运行机制的。但是,需要注意的是:图形化语言是自动多线程处理的。如果程序设计不当,比如图形化代码随意放置,可能会导致自动多线程运行甚至可能会干扰程序设计的初衷。
我们知道,上图中的Stop和Exit LabVIEW都是内置函数,它们的作用分别是停止程序运行和退出LabVIEW开发环境。
Time Delay快速vi我们设定延迟5秒钟。
运行该程序我们会发现,程序总是先停下来,而并不是5秒钟后停下来。因为Stop内置函数的运行结果必然是使程序停下来,即便是其它程序还没有运行完成。
这个例子提示我们在程序设计中使用Stop和Exit LabVIEW要多加小心,尽可能的避免异常停止和退出LabVIEW,因为此时所获得的数据极很有可能不正确。当然,对内置函数和内置vi充分的了解也是必须的。
Time Delay快速vi我们设定延迟5秒钟。
运行该程序我们会发现,程序总是先停下来,而并不是5秒钟后停下来。因为Stop内置函数的运行结果必然是使程序停下来,即便是其它程序还没有运行完成。
这个例子提示我们在程序设计中使用Stop和Exit LabVIEW要多加小心,尽可能的避免异常停止和退出LabVIEW,因为此时所获得的数据极很有可能不正确。当然,对内置函数和内置vi充分的了解也是必须的。






