9.6.3. Action EngineΒΆ

The action engine is also sometimes called a Functional Global Variable (FGV). The naming distinction implies only that FGVs mainly just store data, while action engines can also do calculations or otherwise take some action based on the data. Thus, an action engine is a VI that can store and manipulate data.

LabVIEW VIs are by default not reentrant, which means that only one instance of the same VI may run at one time. This makes a VI a better place than a global or local variable to store data that is shared between parallel loops because we don’t have synchronization issues such as race conditions and deadlock that would otherwise be a problem with parallel executing code.

Warning

Because action engines run as non-reetrant VIs often called by parllel executing code, the code of the action engine can be considered a mutual exclusion critical section, similar to a public synchronized method in Java. (Concepts discussed some in the Network Programming class and more in the Operating Systems class.) Thus, to improve performance, take care to add only code to the action engine that needs mutual exclusion.

If the calculations needed to update the data requires two or more distinct calculations, it might help to implement a sequence of VIs rather than just one action engine. This will allow parallel loops that only need to read data from the action engine to not be held up as much by parallel loops performing lengthy calculations to update the action engine data.

The mechanism that stores the data in an action engine can be either a feedback node or a shift register with uninitialized input. If a shift register is used, the while loop is set to execute only one time when the VI is ran.

We use a case structure with an enumerator control to select what the action engines does when it is called. Depending on the application, typical actions that might be performed include: initialize, update, reset, and read. The read action should always be the default case for the case structure.

../_images/pose_reset.png
../_images/pose_update.png
../_images/pose_read.png

Note

In the LabVIEW programs that we develop, we use three mechanisms to transfer data between parallel loops.

  1. Queues
  2. Global or local variables
  3. Action engines

Both Queues and action engines are what we would call “thread safe”, which means that the sychronization concerns associated with parallel executing code is known to be handled correctly for us. Global or local variables can be used for simple boolean values, but we should always be careful with variables. One could use locking mechanisms, such as semaphores, to ensure correctness of parallel code using variables, but queues and action engines are typically an easier solution.