默认情况下,LabVIEW配置VI用于不可重入执行。不可重入执行中,VI同时被其他VI调用作为子VI时,一次只可一个调用进入并执行子VI。LabVIEW确保非重入子VI的调用方轮流使用子VI。非重入VI只有单个数据空间存储调用方参数、执行中计算的任何临时值以及调用之间非重入VI保持的状态。但是,如果将VI配置为重入执行,LabVIEW可从所有调用方同时进入和执行重入VI。重入执行中,LabVIEW分配数据空间的多个实例或副本,使得调用方程序框图上每个调用点或子VI使用可并行同时执行,每个调用点使用一个单独的副本。

注: (FPGA模块)默认状态下,FPGA VI可重入。

重入执行的类型

LabVIEW的重入VI类型如下:

  • 非重入执行 - LabVIEW为所有子VI实例分配一个数据空间。
  • 共享副本重入执行 - LabVIEW分配一个副本池在调用方之间共享,该副本池最初仅包含一个副本。调用方调用一个共享副本VI时,将从副本池取出一个副本并在调用结束执行后返回该副本。如调用方调用共享副本VI时副本池为空,LabVIEW将为调用新建一个副本,并在执行结束后将副本返回副本池,因此副本池不断增大。
  • 预分配的副本重入执行 - LabVIEW为每个子VI使用分配单独的、非共享副本。

关于VI重入设置的详细信息,请参考VI属性对话框的执行页。

选择使用的重入类型

使用考虑事项 非重入 共享副本的重入 预分配副本的重入
在非初始化移位寄存器中保持状态 保持数据空间的单个实例并在所用调用点使用其状态。 保持状态 - 每个调用点随机从副本池提取副本的数据空间。调用点结果可能共享状态。 维持每个调用点的状态 - 每个调用点有单独的特定副本。
多个同步调用VI的确定性 调用点可能在其他同步调用方后等待 - 子VI实例运行所需的时间取决于队列中该实例之前有多少实例正在等待运行。 可能等待 - 如副本池为空,调用点可能需要等待LabVIEW新建一个副本。副本池不为空时,提取一个副本并将副本返回池中可引起非确定性延迟。 不等待 - LabVIEW在执行前为每个调用点分配一个副本。该方式允许确定性内存使用和执行速度。
同步调用VI不存在时调用开销 中等 - LabVIEW必须检查同步调用方。 最高 - LabVIEW必须原子地从副本池提取副本并将其返回副本池。调用可能需要等待LabVIEWt向副本池添加副本。 最低 - LabVIEW已预分配副本至每个调用点。
内存使用 最低 - LabVIEW只分配一块数据存储空间。 中等 - 同步运行的实例数量达到最大值时,LabVIEW才需要分配副本。 最高 - LabVIEW为每个实例分配一块数据存储空间。
注:(FPGA模块)在FPGA VI中,共享副本重入VI和预分配副本重入VI的行为特性相同。

异步调用重入VI的多个实例

关于异步调用重入VI的详细信息,请参考异步调用VI的多个实例实现并行执行

查看重入VI实例的前面板

每个副本都有单独的前面板。如要在VI副本不运行时查看VI前面板,双击要查看的子VI。也可将重入VI设置为执行时打开前面板。子VI的标题栏包含(副本)表示该VI是副本,而不是原VI。如要从副本访问原VI,选择查看»浏览关系»可重入项。也可在子VI使用前面板:打开方法,通过编程在副本运行时打开各个副本的前面板。子VI标题栏包含(副本)表示当前VI为副本。

重入VI的前面板与非重入VI的前面板交互方式类似,尤其在以下方面:

重入执行的范例

以下部分为重入VI进行等待和不共享数据的示例。

保证子VI实例的同步执行

下列程序框图是用来提醒用户午饭时间休息时间已到。必须对Alarm Timer VI的重入属性进行设置才能保证有理想的结果。

用户指定一个午饭时间休息时间。假设午饭时间为12:00pm,休息时间为10:00am。
Alarm Timer VI等待指定时间。Alarm Timer VI的实例位于程序框图的并行部分,无法预测哪一个实例先执行。假设午饭时间定时器先运行。

如Alarm Timer VI被配置为不可重入执行,休息时间定时器无法在12:00pm之前开始运行,必须等到午饭时间定时器完成执行。这个延迟机制使休息时间定时器无法在10:00am触发一个提醒。为了保证各个子VI实例在合适的时间被触发,必须配置Alarm Timer VI为重入执行。

在调用子VI实例之间存储数据

如需保持特定调用点子VI调用之间的状态,必须使用预分配副本重入执行。例如,创建一个ExpAvg VI用于计算已传递至VI的最新四个数据点的指数平均。LabVIEW可将最新四个数据点作为状态,保存在单个迭代While循环未初始化的移位寄存器中。

另一个VI用ExpAvg子VI来计算两个数据采集通道的指数平均。这个VI监视采集过程中两个点的电压并将计算的结果显示在带状图表上。这个VI程序框图包括两个ExpAvg子VI的实例。两个调用轮流进行 - 一个分配给0通道,另一个给1通道。假设0通道先运行。如果ExpAvg不是可重入的,通道1调用时使用了通道0的计算结果,通道0调用时又使用了通道1的计算结果。如果ExpAvg是可重入的,每个调用就可以独立运行而不相互共享数据。

覆盖定时结构中重入设置

(Real-Time、Windows)可将LabVIEW配置为在定时循环或定时顺序结构中预分配或共享重入VI的副本。例如,如在定时循环或定时顺序结构中放置一个重入VI的共享副本,可将结构设置为预分配在结构中调用的重入VI的实例副本。在结构外调用的重入VI实例将继续共享副本。要在定时循环或定时顺序结构中设置VI的分配,右键单击结构选择共享副本分配,从下列选项中选择:

  • 自动 - LabVIEW根据结构所在的环境决定是否将结构设置为预分配按需分配。LabVIEW将把文本添加至快捷菜单项,以表示LabVIEW选择的设置。例如,如LabVIEW选择预分配,菜单项变为自动(预分配)
  • 预分配 - LabVIEW为每个从结构中调用的重入VI创建一个副本VI。定时循环或定时顺序结构将显示一个图标,表示LabVIEW为结构中的任何重入VI分配副本。
  • 按需分配 - 只有从结构内调用重入VI时,LabVIEW才创建一个副本。定时循环和定时顺序结构将显示一个图标,表示LabVIEW在结构内共享任何重入VI的副本。

调试重入VI

如需调试某个重入VI,可选择文件»VI属性显示VI属性对话框,从下拉菜单中选择执行并勾选允许调试复选框。

如要调试某个预分配副本的实例,打开子VI的相关实例。无法编辑副本VI,但是可以查看VI程序框图。例如,设置断点创建探针启用高亮显示执行过程单步执行

要调试共享副本的VI实例,需在源VI中使用断点、探针和启用高亮显示执行过程。副本VI无法在调用之间保持上述设置。

注:调试应用程序和共享库时,无法调试打开VI引用函数创建的可重入前面板。如可重入前面板是LabVIEW创建的动态链接库的接入点,也无法对其进行调试。