声振论坛

 找回密码
 我要加入

QQ登录

只需一步,快速开始

查看: 2181|回复: 0

[LabView] labview 栈和队列

[复制链接]
发表于 2016-6-1 15:07 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?我要加入

x
  同步控制技术----栈与队列
  (其中有很多图片不是马上就能看到的,查看方法是:鼠标右击不可看图片,选择复制图片地址,然后在浏览器中打开即可。因为本文是摘录的,给各位朋友带来不便,请多谅解!)

  在计算机编程中栈是一个很重要的概念,尤其在汇编语言中,需要不断进栈和出栈的操作.栈是限定在一个表的尾端进行插入(进堆栈)和删除(出堆栈)的线性表.是后进先出结构(LIFO).

  队列的定义和栈的定义是类似的,区别是数据是先进先出(FIFO)

  labview还有一个概念缓冲区BUFFER,典型的比如CHART,它默认保存数据长度是1024.BUFFER的概念和队列是非常相似的,都是一个先进先出的结构.如果我们设定队列的数据长度也是1024.比较一下他们的区别.

  区别一:未达到设定
  开始的时候,队列和缓冲区中都是没有数据的,当有数据进入的时候,队列和缓冲区中的数据在不断地增加,对于缓冲区,因为未达到它最大许可的长度 1024,因此数据是不断第增加的,队列则不同,它的数据是否增加取决于是否有读队列的过程,就是所说的出队,如果出队的速度大于入队的速度,队列中则根本不会有数据.如果没有出队的过程或者出队的速度小于入队的过程,队列中的数据也是不断地增加的.这是第一个区别.

  区别二:到达设定值
  当队列和BUFFER都达到了1024个数据后,这是再有新的数据要进来,队列和BUFFER的表现是不同的,对于BUFFER,它将自动挤出(形象的说法,当然也是编程实现的)最早进入BUFFER的数据,所谓先进先出.而队列则不同.要求进入队列的线程只能被动等待,一直到队列中有别的线程取出数据,队列中有空闲位置.所以队列有调节读写速度线程的能力.

  相同点一:数据进入都是在尾部,(队列插入如果在头部,就编程上面所说的栈了)
  相同点二:对于中间数据都实现了有效的封装,你无法直接提取中间的某个数据,你可以读出中间的数据,但是不能改变当前BUFFER和队列的值.

  LABVIEW提供的队列的功能函数(包括栈),在逐点分析库提供了DBL型的BUFFER,我在另外的日志中专门提到了,这里就不多说了.
  LV队列的函数是基本函数,无法进行深入跟踪,估计应该是采用C++的算法然后封装的,我实际测试过,它的运行效率远高于用数组的方式构成的队列,为了详细说明队列和栈的细节,我还是用数组的形式,然后在介绍LV的队列函数.

  首先看看如何用数组实现栈的功能:
  栈的操作是非常简单的,只有压栈和出栈两个操作(PUSH AND POP)
  我们用AE来实现它.分成三个action: Init,Push ,Pop
  首先严格自定义ENUM,表示三个动作.

1.jpg

2.jpg

3.jpg

4.jpg

5.jpg

  这样我们就完成了栈的AE的制作过程。

  看看它的调用过程。

6.jpg

  10次循环,栈中的数据应该是0,1,2,3,4,5,6,7,8,9。栈的弹出次序应该是9,8,7,6,5,4,3,2,1,0
  运行结果确实如此。

  与栈相反,队列是一个先入先出的数据结构,我们对栈的过程稍微修改一下,就可以得到队列。就不多介绍了。

  下面重点介绍一下LV提供的队列的具体功能。

7.jpg

  分别介绍这8个节点的具体功能:
  1:获得队列(实际是得到队列的参考)它有5个数据端子
  name :String
  队列在LV系统中是名称来区分的,LV系统自己维护一个包含的目前所有队列的表,当你运行这个函数的时候,它首先会查找表中是否已经存在这个队列参考,如果存在,就直接返回这个参考,如果不存在,就建立一个新的队列,并将队列参考加入表中进行维护。这样做的好处是非常明显的,允许我们在任何子VI中,只需要知道队列的名称就可以运行这个函数直接得到队列参考,不用通过全局变量或者数据流输入来得到参考,在一个层层嵌套的VI中想传递一个数据很不容易,也不利于模块化。

  max queue size :I32
  定义的队列的最大长度,当输入-1时,队列长度不受限制,需要注意的是,如果取出数据的速度小于加入队列数据的速度,随着时间的推移,需要的内存会不断地增加,这显然是存在问题的,如果我们没有规定最大长度的话,编程时候要注意自己来协调速度。如果规定的最大长度,当达到最大长度时候,加入队列的线程会一直等待到队列中有空闲位置为止。
  如果已经有同名队列存在,该设置是不起作用的,用的还是第一次运行这个函数时的设置。

  element data type:队列中的数据类型,允许任意数据类型。
  其它两个非常简单,不介绍了。

  2:元素加入队列(Enqueue Element)


  3:预览要出队的元素(读,并不取出)


  4:取得队列当前状态( Get Queue Status)
  这个函数比较重要,它可以获得当前队列的状态信息,包括队列最大长度(设定的),队列名称,当前正在运行的等待取出数据的(运行DEQUEUE)的数量,当前正在运行的加入队列的数量(ENQUEUE),以及当前队列中的所有数据。
  5:释放队列(当程序结束时,进行清理工作,防止内存泄露)


  6:在相反方向插入队列(栈的功能),如果按这种方式插入一定数量,再依次取出,就是上面说的栈的功能。
  对于队列,这个函数可以人工实现队列优先级,最重要的信息可以放在其他不重要的信息前面,比如严重错误,紧急停止等。

  7:取出元素。如果当前队列中无元素可以提取,该函数会一直等待到TIMEOUT或者有数据为止。


  8。清除队列(FLUSH),清除队列中的所有元素。
  可见,队列的基本操作是很简单的,关键是如何在实际工作中正确运用。
  我们首先用AE封装一个队列:

  我们来模拟一下WINDOWS消息,首先定义消息结构。

8.jpg

  然后定义AE,封装队列。

9.jpg

10.jpg

11.jpg

12.jpg

13.jpg

14.jpg

15.jpg

16.jpg

  下面我们来实验一下这个AE,它可以运行在任何一个VI中,为了方便,我们在一个VI中做三个循环,两个写入队列(生产者),一个读取队列(消费者);

17.jpg

  队列的应用范围非常广,经常和状态机联合使用,就是经常提到的队列状态机,有机会我会结合状态机一起介绍。


转自:http://blog.sina.com.cn/s/blog_4cd90db30100b2k3.html

回复
分享到:

使用道具 举报

您需要登录后才可以回帖 登录 | 我要加入

本版积分规则

QQ|小黑屋|Archiver|手机版|联系我们|声振论坛

GMT+8, 2024-5-2 10:40 , Processed in 0.603832 second(s), 24 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表