作者:ruanqizh… 教程来源:vihome 点击数: 781 更新时间:2008-6-15 荐 ★★★ |
在现在常用的文本编程语言(C++, Java, C#)中,调用子函数时的传参方式主要是传引用方式,就是说,告诉被调用的函数的是参数所在的位置,而不是参数的数据。C++ 为了保持和 C 语言的兼容,一般的简单数据还是使用值传递,但对于大块的数据,比如数组,字符串,结构,类等等,也基本上都是引用形式传递的。 值传递的方式的缺点是显而易见的:每次调用子函数的时候,需要把数据拷贝一份,耗费大量的内存。传引用的方式,不需要每次都拷贝数据,节省了内存空间,和复制数据的时间。但是传引用的安全性不如直接传值,因为传引用的时候,数据所在的内存也可以被其它函数访问,这在单线程下,问题不大。但是多线程下,就不能保证数据的安全了。 理论上,一个数据流驱动的编程语言,可以只采用值传递。数据在每一个联线分叉的地方,都做一个拷贝。这样任何一个节点所处理的数据都是它专用的,不需要担心线程之间会相互影响。在设计 LabVIEW 程序时,可以假设 LabVIEW 就是这样子工作的。但是 LabVIEW 的实际工作情况比这要复杂些,它在不违背数据流原则的前提下,做了一些优化以避免过多的复制数据。 在某些时候,一个节点得到了输入数据,LabVIEW 如果能够确认这个输入数据的内存肯定不会被其他部分的程序代码使用到,并且恰好节点的一个输出需要一块内存,LabVIEW 就不在为输出数据令开辟一块内存了,而是使用那个输入数据所在的内存。这叫做缓存重用。 LabVIEW 中有些节点的输入输出数据类型完全不一样,比如数组索引节点,输入是一个数组和索引,输出是一个数组的元素。输入和输出的数据类型一般情况下完全不同,所以必须未输出数据新开辟一块内存,根本不可能做到缓存重用。有些节点,总是有相同类型的输入输出,比如加法节点,输出值的数据类型总是和其中一个输入同类型(fixed-point 数据类型是个例外)。LabVIEW 要考虑尽量在这些节点使用缓存重用。 LabVIEW 虽然不能设置数据传递给一个节点时,使用值传递还是引用传递,但是 LabVIEW 中有一类专门的“引用型控件”,用来保证大块的数据不被频繁复制,或者在不同的线程内对同一内存做数据操作。一般叫做 xxx refnum 的控件都属于之一类,他们所代表的数据(也可用于表示某个设备)是不随着数据线流动的。程序上的连线出现分叉,虽然 refnum 这个值本身可能会被复制,但它所指向的数据是不会被拷贝的。 另外,如果一定要在 LabVIEW 代码中实现传引用,可以通过以下的方法:做一个全局数组变量,把数据存在数组里。VI 间传递的信息是数据在数组中的索引,一个表示序号整数值,就相当于是这块数据的引用。这样,所有对块数据的操作都是在同一内存中的,并且不同线程可以同时对这块内存做修改。 |
文章评论(0条评论)
登录后参与讨论