After dividing tasks in an application into separate Timed Loops or VIs of different priorities, you might need to communicate between the loops on a block diagram or between the different VIs on the RT target. Use shared variables, Real-Time FIFO VIs, functional global variables, and global variables to share data in a VI or between VIs running on an RT target.
Use single-process shared variables to share data between two locations in a block diagram or between VIs running on an RT target. Right-click an RT target in the Project Explorer window and select New»Variable from the shortcut menu to open the Shared Variable Properties dialog box, which you can use to create a single-process shared variable.
The Real-Time Module adds a real-time FIFO—first in, first out buffer—to the shared variable. By enabling the real-time FIFO of a shared variable, you can deterministically share data without affecting the determinism of VIs running on an RT target. From the Real-Time FIFO page of the Shared Variable Properties dialog box, place a checkmark in the Enable Real-Time FIFO checkbox to enable the real-time FIFO of a shared variable.
Single-process shared variables provide an communication method that is easy to use and deterministic when you enable the Real-Time FIFO.
Use the Real-Time FIFO functions to share data between VIs running on an RT target. An RT FIFO acts like a fixed sized queue, where the first value you write to the FIFO is the first value that you can read from the FIFO. An RT FIFO ensures deterministic behavior by imposing a size restriction on the data you share and by preallocating memory for the data. You must define the number and size of the RT FIFO elements and ensure that you do not attempt to read and write data of different sizes to ensure the deterministic performance of the FIFO.
Use the RT FIFO Create function to create a new FIFO or to create a reference to a FIFO that you previously created. Use the RT FIFO Read and RT FIFO Write functions to read and write data to the FIFO. Use the RT FIFO Delete function to delete a reference to an RT FIFO and release the memory allocated to the FIFO on the RT target.
An RT FIFO can wait until an empty slot becomes available for a write operation or wait until a value is available for a read operation. You can specify a read and write mode for an RT FIFO that defines the way you read a value from an empty FIFO or write a value to a FIFO that does not have an empty slot. You can specify one of the following modes for reads and writes:
polling—Use this mode to optimize the throughput performance of read and write operations. The polling mode continually polls the FIFO for new data or an open slot. The polling mode responds quicker than the blocking mode to new data or new empty slots, but requires more CPU overhead. Use the timeout in ms input of the RT FIFO Read or RT FIFO Write function to specify the amount of time that a write operation should poll for an empty slot or the amount of time a read operation should poll for new data. You also can use the overwrite on timeout input of the RT FIFO Write VI to specify whether to overwrite the oldest value in the RT FIFO when the value of the timeout in ms input expires.
blocking—Use this mode to optimize the utilization of the CPU during read and write operations. The blocking mode allows the thread of the VI to sleep while it waits, allowing other tasks in the system to execute. Use the timeout in ms input of the RT FIFO Read or RT FIFO Write function to specify an amount of time a read operation can wait for a new value or an amount of time a write operation can wait for an empty slot. You also can use the overwrite on timeout input of the RT FIFO Write VI to specify whether to overwrite the oldest value in the RT FIFO when the value of the timeout in ms input expires.
![]() |
Note If you use the RT FIFO Create function to return a reference to an existing RT FIFO, the reference uses the read and write mode of the existing FIFO and ignores the modes specified with r/w modes. |
Use functional global variables to pass data between VIs. A functional global variable is a subVI set to subroutine priority. The subVI contains a While Loop with a nested Case structure for read and write access. The following figure shows the read and write cases of the Case structure for a functional global variable.

The While Loop contains uninitialized shift registers that store data. A functional global variable receives an action input that specifies which task the VI performs, as shown in the previous block diagram, by the Mode input parameter. Any subsequent calls to the functional global variable can access the most recent data. Functional global variables resemble queues because you can add more shift registers to store a longer history of values. You also can add more than one set of shift registers to pass more than one set of data.
Unlike global variables, you can implement functional global variables such that they are not a shared resource. Right-click a subVI set to subroutine priority and select Skip Subroutine Call If Busy from the shortcut menu to force the execution system to skip the subVI if the subVI is currently running in another thread. Skipping a subVI helps in time-critical VIs because the VI does not wait for the subVI. If you skip the execution of a subVI, the subVI returns the default value for that data type and not the default indicator value. For example, the default data type value for numerics is zero, strings and arrays default to an empty string, and Booleans default to FALSE. If you want to detect the execution of a functional global variable, wire a TRUE constant to a Boolean output on the functional global variable block diagram, as shown in the previous diagram. If the Boolean output returns TRUE, the functional global variable executed. If the Boolean output returns the default value of FALSE, the functional global variable did not execute. Skip functional global variables in time-critical VIs but not in lower priority VIs. In lower priority VIs, you can wait to receive non-default values.
Functional global variables can be a lossy form of communication if a VI overwrites the shift register data before another VI reads the data.
Use global variables to access and pass small amounts of data between VIs, such as from a time-critical VI to a lower priority VI. Global variables can share data smaller than 32-bits, such as scalar data, between VIs deterministically. However, global variables of larger data types are shared resources that you must use carefully in a time-critical VI. If you use a global variable of a data type larger than 32-bits to pass data out of a time-critical VI, you must ensure that a lower priority VI reads the data before the time-critical VI attempts to write to the global again.
Global variables are a lossy form of communication, meaning the global variable can overwrite the data before you read the data. Tasks in a lower priority VI might not have enough processor time to read the data before other tasks in a different VI overwrite the data.