LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Global Variables Question

I am working on a project that involves controlling the temperature in two vacuum chambers. Each chamber will have its own LabVIEW program, containing a number of sub-VIs and global variables. Both of these programs will be running on one computer. My question is concerning the global variables. Since all of the global variables are located in one location and both chamber programs will be accessing it, will there be any problems that may arise from this?
0 Kudos
Message 1 of 14
(5,199 Views)
If you are creating exe files then there is no sharing of global variables between the applications. If you are running in the development mode, then the globals will be shared and there is the possibility of problems. The best way to avoid problems is to not use global variables at all but if you can't do that, they should unique names.
0 Kudos
Message 2 of 14
(5,189 Views)
To elaborate more on what Dennis said, the main problems from globals can come from uninitalized globals (you write from one place, but that place hasn't been run yet), globals which are written to from different places (race conditions) and memory issues (if you're using large data structures). If you don't have these, you shouldn't have any problems. Also, if you're running both programs in the same EXE, the globals will be shared.

___________________
Try to take over the world!
Message 3 of 14
(5,179 Views)
Global variables are generally considered very poor programming style, especially when they are used in an uncontrolled manner without appropriate locking mechanisms.

Although most good LV programs avoid them completely, there are a few situations in which they can be used without trouble, such as sharing small pieces of fairly static data between two programs. As a good rule of thumb, only one program should write to the global variable, and global variables should not be used for transferring data which requires the readers to detect each change in data.

In my experience, most programs which use global variables attempt to use them to do much more than this, and also use them incorrectly (i.e. without appropriate locking). The problems you will see will, of course, be dependent upon your particular implementation, but some of the problems you are likely to see include the following:

1. Missed data/updates - Because global variables contain no buffering and no control to determine if a value has been read, they are an extremely poor way of exchanging data between two programs. If one program happens to update the variable twice before the other program reads it, the first update will be lost.

2. Race conditions - A race condition is a situation where the behavior of a program is dependent upon which threads the processor happens to give priority to. In essence, programs containing race conditions behave randomly (for example, they might run fine 100 times in a row, and then fail catastrophically on the 101st). Race conditions make programs very unreliable, and are extremely difficult to debug (the random nature of the race condition makes it very difficult to reproduce, and most debugging tools are useless as they effect the execution speed of the program). Race conditions can be caused by a number of things, but one of their most common sources is multi-threaded code which accesses global resources (exactly what you have). Multi-threaded code accessing global resources, such as global variables, often contains "critical sections", which are sections where access to the resource must be controlled to avoid a race condition. Unless these critical sections are locked using some mechanism (semaphores are a tool designed for this type of locking) another thread can gain control of the resource in the middle of the critical section and create a race condition.

3. Inefficient memory usage - Any time a global variable is read it creates a copy of the data in the global variable. This isn't a problem with small data types like a double or a Boolean, but if you use global variables to transfer large or complex data types like clusters or arrays, you will see a significant performance decrease in your programs in terms of both memory and execution speed.

4. Difficulty of maintenance - I sort of mentioned this one under Race Conditions, but debugging or maintaining a program which uses global variables is a huge pain because at any given time there are multiple threads controlling the value of the variable. Timing in these programs becomes a variable which is almost impossible to control, thereby making their behavior non-deterministic (i.e. unreliable).

There are other potential problems, but those are the most common.

When analyzing your program, I would start by removing any unnecessary global variables from your code (which is probably most of them). For example, using a global variable to transfer data to a SubVI is just lazy, the data should be passed using the connector pane, and if the SubVI needs to communicate back to the main VI before it completes, it should use control references or the more advanced synchronization mechanisms such as queues or notifiers.

Next, you should carefully analyze how the remaining global variables are used in your code, and identify and protect critical sections by using semaphores (note that you don't necessarily have to use the built in semaphores, you could implement your own, but doing this properly is tricky). If any of the global variables are used in an inappropriate manner, replace them with a better synchronization mechanism. For example, if a global variable is being used to periodically transfer data between to programs, replace it with a named queue to provide buffering in case one program runs faster than the other.

Hope that helps.

Regards,
Ryan K.
Message 4 of 14
(5,178 Views)

I agree with most of what Ryan says. I've been programming with LabVIEW since it was 1.0. Over time I have found that if your not careful with local variables data will get either lost or will be updated late. I have gotten away from using locals and went to properity nodes for small amounts of data or instrument calls.

Recently I was given that task to creat a program for a customer product which was incredibly hard since the documentation was incorrect and the customer was on the other side of the world. When I finally figured out the command syntax I used globals to store them and then present them to be entered into a file. I did not have any conflicts or race conditions. The program worked as advertised. The customer was happy and other people took the credit. Now they want me to disassemble the globals and use locals. Is there any thing gained by switching from one to the other.

Most of my programming is instrument control with data placed into arrays or clusters for reuse. I need to get my mind right.

 

Jr. Cigar

0 Kudos
Message 5 of 14
(4,781 Views)

The problems with Global Variables aren't really specific to Global Variables, most of them refer to unprotected global data in general, particularly in an unbuffered manner.  Therefore, you get the same problems using your controls to store data (i.e. using local variables or value propterty nodes).  As a side note, last I checked, value property nodes actually have worse performance than local variables (and are otherwise the same, unless you are using value(signaling)) because they have the potential to cause an additional thread swap into the user interface thread.  They are nice because they have the error clusters which make it easy to control your dataflow though.  As far as globals vs locals, there really isn't a big difference.  If you are using them exclusively to store data it probably makes more sense to use globals just so you don't end up with a bunch of unneccessary controls on your front panel.  Both will have the same potential problems as far as memory efficiency (generally not a big deal on modern PCs), race conditions, and overflow/underflow.  If you've already solved these problems using globals (which it is certainly possible to do, just requires a little more thought than using a safer mechanism) then you won't get any benefit by switching to locals.  In general, while refactoring code is an admirable task, if it isn't broken, don't fix it.

If you do decide to replace the globals with another global data storage method, there are two I use regularly.  The first is functional global variables (a.k.a. LV2 style globals).  These are good for storing relatively static data that isn't being streamed between parts of the program.  At their simplest (i.e. with just a "get" and a "set" command), these aren't actually any better than a regular global, but if you implement a functional global with robust commands that actually manages the data within the functional global (i.e. have an "increment" command rather than calling "get", incrementing the value, then calling "set") this provides you with some protection from race conditions and, depending on the implementation, the potential for more efficient memory usage.  A good rule to follow is that any critical section of code (a section where you are performing operations while expecting the global value not to change) should be inside the functional global, which will then protect it like a semaphore.  You can also implement buffering within a functional global to protect yourself from overflow or underflow, but that's really overkill, since if you need buffering you're better off using the second common global data storage/transfer mechanism, which is some form of queue (usually the basic queue is the best bet on a windows platform, but you can achieve the same thing using other types of queues such as Real-Time FIFOs or even user events).

The OOP capabilities in LV8.20 also offer some nice ways to organize your global data, to be honest, I've been so busy I haven't had a lot of time to play with them yet, but at the least they offer ways to protect your data similar to a functional global.  Since the LV implementation passes by value however, you'll still need another global storage mechanism to actually store the objects.

If you're interested in more information on these, our training courses (particularly LV Basics II and LV Intermediate I) cover the proper use functional globals and queues.

Hope that helps,

Ryan

P.S. A tip for using the forums: it's generally not a good idea to post on old topics like this, since only people who are subscribed to the topic will notice the post and subscriptions expire after a while.  Luckily I still had an active subscription for this post, but in general it's best to start a fresh one so everybody sees it.

Message 6 of 14
(4,762 Views)
I am new to the forum. I did not look at the date.  Sorry
 
Jr Cigar
0 Kudos
Message 7 of 14
(4,736 Views)
Hi
Actualy i try to create a program using LV2 global but see a problem. This program call asyncronusly four identic Vi (slave)(just the name are different) and inside those Vi's i have  one common  LV2 global . This LV2 global are using few times in each Vi's and in different loop in each Vi's.
When i run only one (slave) that  ok and there is no competition betwen loops and different  call of this LV2 global, but when i run more than one Vi(slave) the data are muddle.
My question is : The LV2 data integrity are there garantee only if the  LV2 run in only one Vi  in same time ?
I don't think  semaphore can soved my problem, because like there is no priority ,perhapse the first Vi take the semaphore all the time and not the other.
Regards
Eric
0 Kudos
Message 8 of 14
(4,678 Views)

An LV2 global is just what it is called - a global. That means that it is relevant for all the VIs that call it at the same time and the different VIs will use the same global at the same time and mess it up. To see this, open the VI hierarchy window and you will see that all the VIs are calling the same global.

Some options -

  1. Create different actions and data in your global for each of the subVIs.
  2. Create a seperate LV2 global for each VI, in the same way that you created seperate VIs.
  3. Use another mechanism for communicating between your loops, like notifiers or queues, or even locals, in certain cases.

I would suggest avoiding option 2, because duplicating VIs is a problem when you want to change code. This also goes for your currently duplicated VIs.

If you want to have several instances of the same VI, you can set the VI to reentrant in the VI Properties>>Execution window or change it to a VI template, depending on what you want to achieve.

To learn more about LabVIEW, I suggest you try searching this site and google for LabVIEW tutorials. Here, here, here, here and here are a few you can start with and here are some tutorial videos. You can also contact your local NI office and join one of their courses.
In addition, I suggest you read the LabVIEW style guide and the LabVIEW user manual (Help>>Search the LabVIEW Bookshelf).


___________________
Try to take over the world!
Message 9 of 14
(4,675 Views)
Hi Tst thanks for your reply
Like you tell in your 1) Proposition I have make a difference mechanism to modify specifics datas (link with the specific slaveVi ) in my common LV2 globale. I use a array containing data and the index are specific to each(slave) Vi, but that don't run. Do you think that of i use specific register for each (slave) Vi data instead of array, it's better ?
Regards
Eric
0 Kudos
Message 10 of 14
(4,668 Views)