SubVI Called Simultaneously in Different VIs Closes When One VI Closes

Updated Jun 6, 2023

Reported In

Software

  • LabVIEW

Issue Details

I have a subVI, such as a Functional Global Variable, which is called in two or more different VIs. These VIs are not dependent on each other, and are not in the same project. The VIs execute correctly, but when I close the VI from this set that I ran first, the other VIs error out. The errors thrown by the other VIs indicate that the subVI that all of my VIs called closed when the first VI closed, even though the subVI was still being called by my other VIs. What is causing this behavior, and is there any way for me to prevent it?

Solution

This behavior is an expected component of LabVIEW, and is caused by the VI Call Hierarchy and how it affects calls to subVIs from programs running asynchronously, or in separate threads without dependence on the results of previously executing VIs. VIs in LabVIEW can be called asynchronously by running two or more VIs which are in separate projects, running two or more VIs in which at least one is not associated with any projects, or by manually executing an asynchronous VI call using a Start Asynchronous Call Node.

The cause of the described behavior is illustrated in the below example, with two asynchronous VIs and one subVI being called by both VIs.

Illustration outlining why closing the first caller of a subVI in an asynchronous call stack causes subsequent callers to experience errors.

VI 1 begins first, and executes its first call to the subVI, which is loaded into memory and begins communicating with VI 1. Since VI 1 was the first to call the subVI, the subVI is tied to the thread of VI 1, and will continue executing as long as VI 1 is executing. Later, VI 2 begins and executes its first call to the subVI, which is able to respond since it is currently loaded into memory by VI 1. Later, VI 1 closes, and since the subVI was initially called by VI 1, it also closes and is removed from memory. However, VI 2 is still running and is still trying to communicate with the subVI, which is no longer open - this results in VI 2 getting an error pointing to the element in the subVI it was communicating with not existing anymore.

Note that this error wouldn't occur if VI 2 was closed first in this scenario - because the subVI is tied to the execution of VI 1, it will only become unreachable if VI 1 shuts down. Thus, if different VIs started operating and communicating with the subVI while VI 2 was running, they would still be able to communicate with the subVI after VI 2 closed as long as VI 1 is still running.

In order to prevent this behavior from occurring, you should include an initialization VI in your program that will call the communicating subVI into memory before any VIs that need to use it start up. Be sure to call any references that the subVI contains, such as notifiers, in this initialization VI as well to ensure they stay available during your code's operation.

Diagram showing how an initialization VI can prevent subVIs from closing when called by asynchronous VIs.