Qizhen's profileLabVIEWPhotosBlogListsMore Tools Help

Blog


    如何使用 VI 的重入属性(Reentrant)

        在 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 在不同的地方调用一个可重入 VI 时,会给它另外分配一个独立的数据地址空间。这样就做到了线程安全。在两个线程执行的子 VI 使用两份在不同的地址存储的数据,也就不会造成混乱。但是千万要注意, 这个“在不同的地方”调用:不可重入的 VI 的局部变量与 C 语言中非静态变量的含义是不同的。在后面提到的计数器的例子可以验证这一点。

         我觉得我说得挺清楚了,出道题目给大家测试一下:


    图2:延时子 VI


    图3:计算延时的主 VI

        图2 是一个子 VI 的代码,功能是延时 1000 毫秒。图3 是主 VI 的代码,并行调用同一子 VI 两次,并计算程序的执行时间。运行主 VI,total time 的值是多少?
        答案在文章最后。

        这是可重入 VI 的一种用途,即希望在不同的线程里同时执行同一个子 VI。
        另外还有一种情况下,也可以用到可重入 VI:即需要使用到子 VI 中局部变量保存的数据,而在不同的调用处,这些数据是独立不同的。这句话可能解释得不那么清楚,看下面例子就会比较容易理解些。


    图4:计数子 VI

     
    图5:测试计数的主 VI

        图 4 是一个可重入子 VI 的代码,功能是计算这个VI被运行的次数,每运行一次,输出的 count 值就增加1。图5 是调用它的主VI,用于演示这个计数器。执行主VI一次,output 1 和 output 2 的值分别是 10 和 20,表示这个子 VI 在两处分别被调用了 10 次和 20 次。
        如果把图 4 中的 VI 改为不可重入,则 output 1 和 output 2 的输出值是不确定的。大家可以自己试一试,再想一下原因。

        当使用递归结构时,参与了递归调用的 VI 是需要被同时调用多次的。因此这些 VI 中的变量必须是局部的,也就是说参与了递归调用的 VI 必须都被设置为可重入。参考:在 LabVIEW 中实现 VI 的递归调用

     

        测试题目答案:如果图2的子 VI 没有设置为可重入,则 total time = 2000;如果设置为可重入则 total time = 1000。

    下载示例:

         计算两次调用可重用 VI 的延时
         利用可重用 VI 计数

    相关文章:

        我和 LabVIEW
        LabVIEW 程序的内存优化
        LabVIEW 程序中的线程 1 

     

    编辑

     

     

     

     

    Comments (12)

    Please wait...
    Sorry, the comment you entered is too long. Please shorten it.
    You didn't enter anything. Please try again.
    Sorry, we can't add your comment right now. Please try again later.
    To add a comment, you need permission from your parent. Ask for permission
    Your parent has turned off comments.
    Sorry, we can't delete your comment right now. Please try again later.
    You've exceeded the maximum number of comments that can be left in one day. Please try again in 24 hours.
    Your account has had the ability to leave comments disabled because our systems indicate that you may be spamming other users. If you believe that your account has been disabled in error please contact Windows Live support.
    Complete the security check below to finish leaving your comment.
    The characters you type in the security check must match the characters in the picture or audio.

    To add a comment, sign in with your Windows Live ID (if you use Hotmail, Messenger, or Xbox LIVE, you have a Windows Live ID). Sign in


    Don't have a Windows Live ID? Sign up

    lcz_1260wrote:
    赞一个啦!又学会一种技巧!
    Mar. 23
    Qizhen Ruanwrote:
    如果你的VI不是很复杂,可以发信给我,我帮你看一下。
    Feb. 3
    颖 陈wrote:
    你好,我现在初学Labview,需要调试一个VI,这个Vi曾经能够正常运行的,可是现在总显示有错误,我又找不出来,你能帮我看看吗?
    Jan. 22
    No namewrote:
    好强啊 我刚开始学着用~~
    Jan. 17
    Qizhen Ruanwrote:
    kimi,你可以把你的VI或者截图发给我 ruanqizhen@gmail.com,我看一下才能知道是什么问题。
    July 9
    Picture of Anonymous
    kimi wrote:
    你好。刚拜读你写的文章,受益匪浅。但是在第二个例子时,图4,计算子VI,我做了一个一样的子VI,但是发现count输出一直是0,我用Probe在各个点进行了测试,程序是运行的,正确的。但是while语句外面的count控件输出一直为零。我特意将while中的i添加了indicator,在while语句内有输出,但在while语句外加上一个indicator,数字仍然没有变化。请问这是什么原因!!!
    July 7
    Picture of Anonymous
    飘絮 wrote:
    辛苦了!谢谢
     
    Sept. 16
    Picture of Anonymous
    (没有名称) wrote:
    又知道了一样,很高兴,谢谢
    Aug. 7
    清扬wrote:
    我也是labview的爱好者啊   以后多多交流呀~
    July 22
    yiwrote:
    先收藏,再仔细学。谢谢好文章
    July 21
    onemade -wrote:
    呵呵 同楼上的
    July 21
    洋 文wrote:
    原来是个LABVIEW高手啊~我前段时间的时间就是用LABVIEW写程序~HOHO~有缘啊~以后有这方面的问题就来问你啦~
    July 20

    Trackbacks (1)

    The trackback URL for this entry is:
    http://ruanqizhen.spaces.live.com/blog/cns!5852D4F797C53FB6!1519.trak
    Weblogs that reference this entry