pattern_reentrant_vi #13
Replies: 5 comments 8 replies
-
感谢阮老师,这些内容非常有价值。最近在用LabVIEW编写并行程序,需要调用同一个子vi,才发现子vi的默认设置是非可重入的。函数选版里自带的函数基本都是可重入的,导致我以为自己写的子vi也是可重入的。我个人认为,近些年计算机内存快速增大,价格快速降低,子vi默认非可重入节约的一丢丢内存空间,反倒耽搁了很多运行时间。 |
Beta Was this translation helpful? Give feedback.
-
利用map缓存递归中的map函数labview中找不到,是我没有这个工具包吗?不过我写了个利用变体作为缓存的,感觉功能一样,确实挺快的 |
Beta Was this translation helpful? Give feedback.
-
请问阮老师最后那个练习题如何实现,算法思想清楚,但是不知道如何下手 |
Beta Was this translation helpful? Give feedback.
-
“普通 VI 为什么不能被递归调用”部分第三段中,“但是不能被用于地递归调用。”多个地字 |
Beta Was this translation helpful? Give feedback.
-
之前博客上的相关文章,搬到这里: 如何使用 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 一定要等一个执行完,再执行另一个。 其原因是,LabVIEW 会为每个 VI 都开辟一块内存用于数据存储。作为子 VI,每次被调用,它的局部变量的数据都是被存在同一地址的。与 C 语言相对照,在默认情况下,VI 是不可重入的,VI 中所有的局部变量都是静态变量。如果 LabVIEW 在不同的线程下执行同一 VI,那么两个线程就会同时对这一块数据地址进行读写,就会导致这一块地址内数据的混乱。为避免此类不安全情况的出现,LabVIEW 必须等待一个子 VI 执行结束,再执行另一个子 VI。 我觉得我说得挺清楚了,出道题目给大家测试一下: 图2 是一个子 VI 的代码,功能是延时 1000 毫秒。图3 是主 VI 的代码,并行调用同一子 VI 两次,并计算程序的执行时间。运行主 VI,total time 的值是多少? 这是可重入 VI 的一种用途,即希望在不同的线程里同时执行同一个子 VI。 图 4 是一个可重入子 VI 的代码,功能是计算这个VI被运行的次数,每运行一次,输出的 count 值就增加1。图5 是调用它的主VI,用于演示这个计数器。执行主VI一次,output 1 和 output 2 的值分别是 10 和 20,表示这个子 VI 在两处分别被调用了 10 次和 20 次。 当使用递归结构时,参与了递归调用的 VI 是需要被同时调用多次的。因此这些 VI 中的变量必须是局部的,也就是说参与了递归调用的 VI 必须都被设置为可重入。参考:在 LabVIEW 中实现 VI 的递归调用 测试题目答案:如果图2的子 VI 没有设置为可重入,则 total time = 2000;如果设置为可重入则 total time = 1000。 |
Beta Was this translation helpful? Give feedback.
-
可重入 VI 和递归算法
https://lv.qizhen.xyz/pattern_reentrant_vi
Beta Was this translation helpful? Give feedback.
All reactions