Labview 学习笔记

更新时间:2023-11-28 10:23:01 阅读量: 教育文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

reference死锁问题

LabVIEW中的引用经常需要和“In Place Element Structure”配合使用。In Place

Element Structure 对一个引用的数据进行处理时,为了保证多线程安全,它会锁住引用指向的数据;其它线程若需对同一数据做操作,必须能这个In Place Element Structure中所有代码执行完毕才可,这样就避免了多线程读写同一内存数据所产生的竞争问题。

举例来说,下面这段程序的执行时间是1秒:

而下面这段程序的执行时间则是2秒:

因为第二段程序中的两个In Place Element Structure必须顺序执行。

有了“锁住”这个操作,就有不小心造成死锁的可能。比如对于同一数据的引用,千万不能嵌套使用In Place Element Structure,否则就会死锁:

在上面这个示例中,程序运行至内层的In Place Element Structure,就会停在这里等外层In Place Element Structure运行结束,释放它锁住的数据;而对于外层In Place Element Structure来说,它内部的全部代码要运行结束,它才结束。因而它们相互等待,造成了死锁。

Packed Project Libraries 2 –与Library的比较

acked Project Library 从名字上来看,就是被包装好了的Project Library。Project Library 是编程时候由程序员创建出来的。比如下图这个工程,我在里面创建了一

个叫做“My Algorithm Library.lvlib”的工程库。它包含两个VI,其中一个是私有的。

Packed Project Library 并不是手工创建的,他是通过一个项目的生成规范,从

Project Library 编译而来的。比如上图的项目,我创建了一个Packed Library类型的生成规范。我在这个生成规范中指定把“My Algorithm Library.lvlib”编译成Packed Project Library 。

编译的结果是在我指定的路径下生成了一个名为“My Algorithm Library.lvlibp”的文件。它的后缀名仅比Packed Library多了一个字母p。 双击这个文件,可以打开它,看到他里面包含的VI:

如果需要在其它项目中使用到这个Packed Project Library,我们可以直接把它加到另一个项目中去,下图是一个演示项目:

Packed Project Library 看上去和 Project Library 非常相似,用法也完全相同。 Packed Project Library 与 Project Library

都是将功能相关的一组VI封装起来的方法; ? 库中的VI可以具有层次机构;

? 库中的VI都带有名字空间,名字空间是带有后缀名的库名; ? 都可以方便的放在项目管理器里使用

?

尽管它们十分相似,Packed Project Library 与 Project Library 相比,还是有一些明显区别的:

? ? ? ? ? ?

Packed Project Library 是通过编译生成的;

Packed Project Library 中的VI是编译后产生的,它们不能被修改;

Packed Project Library 包含有私有VI,但用户无法看到也不能使用它们; Packed Project Library 把VI,.lvlib以及其它用到的文件都打成一个压缩包,用户在磁盘上就只能看到一个.lvlibp文件,看不到VI文件; Packed Project Library 很适合作为最终产品发布给用户使用;

在项目中使用Packed Project Library 可以缩短编译时间,因为Packed Project Library 中的VI是已编译好的,不会再随项目编译一遍。(这一条先这样写上,但我还需要再深入研究一下)

LabVIEW中LVClass数据转换成XML格式的问题

前一段时间,一个同事的程序出了问题。他在程序中把一个LVClass类型的数据转换成XML格式,再保存成文件。但是从文件中把数据转回成 LVClass时,却出了问题:在调用“Unflatten XML”这个函数时,程序有时出错,有时又不出错。他的程序中使用了大量的LVClass,并且它们之间有着复杂的继承与包含关系,以至于花了两三天的事件,才找出问题所在。其实是个简单的问题,只是在设计程序时他没有意识到。

我做了一个简化的程序,可以重现这个问题:

首先,给一个子类的对象设置一些数据。然后把它当做父类类型的数据,平化成XML文本,存盘:

关闭LabVIEW,然后重新打开LabVIEW。再编写一个反向程序,把XML数据转换成父类类型的数据:

发现Unflatten From XML函数返回一个错误,value中是一个空的数据。

错误产生原因如下:在把子类数据转换成父类数据类型,这个类型虽然是父类的,但其数据仍然是子类的。再转换成XML格式,XML格式中记录的仍然是子类的数据。

在反向过程中,Unflatten From XML拿到的数据是子类的,但它企图转换时,却发现内存中没有子类的类型信息,因此它也就不知道如何转换这个数据,所以报错。 如果这个程序稍微改动一下,把XML数据直接转换成子类的数据,就不会出错了:

实际上,子类的数据总是可以用父类来表示的。因此这个XML数据亦可以直接被转换成父类的类型,但前提是,一定要保证子类的类型别家在到内存中去了。只要在程序中放置一个子类的对象,自然就可以把子类加载至内存。像下面这个程序就可以正常工作:

这个实验反映出两个问题:

1. 把XML中的内容如果是属于某个LVClass类型的数据,把这些数据转换回LVClass数据时,那个LVClass一定要已经存在于内存才行。

2. 在之前的一篇文章“LvClass 的一个效率问题”中提到过:当子类被加载如内存时,它所有的父类也会被加载入内存。但反过来并不成立。因为一个类有哪些父类是确定的,父类的地址就记录在子类中。但一个类并不知道他会有多少子类,任何人都可以从它派生出不同的子类来,因此它在装入内存时,不可能把自己的子类也都装进来。

LabVIEW中实现链表、树等数据结构

LabVIEW自带的数据结构只有数组和队列。多数情况下,这两种数据结构足够开发者使用了。但是,我平时使用C++和C#语言更多一些,所以编写程序时常常会想到使用其它编程语言中常见的数据结构比如链表(List)、树(Tree)等。 LabVIEW中也可以编程实现这些数据结构,一个比较直观易懂的编程方法是基于LabVIEW中的类和引用来实现各类数据结构。我在《我和 LabVIEW》一书的第13.3.5节中介绍了一个简单的链表容器的实现方法,它是基于LvClass编写的,数据流驱动的一种容器。但是正如我在书中提到的,它虽然和有一些和文本编程语言中的链表相类似的地方,但本质并不相同。文本编程语言中的链表,树等数据结构离不开引用(或指针),节点之间是通过引用来相互关联的。LabVIEW可以为数据创建引用,因此也可以方便的实现与文本语言中功能相同的数据结构。 这里插一段,介绍一下数据结构和数据容器的关系,我自己理解是这样的:数据结构侧重于数据的存储方式,比如如何排序;数据结构在加上与此结构相关的操作方法,比如添加删除数据等方法,就构成了一个数据容器。脱离了操作方法,单纯的数据结构用处非常有限。因此,我文章中在提到数据结构或者数据容器时,指的都是同一回事:数据结构和相关的方法。

为了介绍如何在LabVIEW中实现一个数据结构,我打算以双向链表为例,讲解一下如何编写它。

双向链表中每个节点都会记录上一个节点和下一个节点的位置。因此,在双向链表中,可以从一个节点直接跳转到它的上一个或下一个节点上去,也就是正向或反向遍历整个链表。可以直观的想到,使用LvClass实现这样的节点,只要为这个节点创建一个类ListNode,并且这个类有两个成员变量,它们的类型都是ListNode的引用,分别用于指向前一个和后一个节点就可以了:

本文来源:https://www.bwwdw.com/article/qn1t.html

Top