LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Why use queue to stop parallel loops?

The Network Streams examples included in LabVIEW 2010 contain parallel loops, one being an Event loop with a Stop button and the other being a data processing loop designed to run until Stop is pushed (or received).  The method used to stop the second loop is to create a queue, and have the first loop put a boolean (value doesn't matter) on the queue.  The second loop periodically tries to remove an element from the queue (but doesn't use the element) with a timeout of 0 -- since the queue is empty (until the first loop exits), it (almost always) times out, which is used to keep the second loop running.

 

All three of the Network Streams examples use this construct to get one loop to stop a parallel loop.  It seems slightly arcane to me to create a queue just for this purpose.  What is the drawback to using a local variable (say a local copy of the Stop control) to stop the second loop?  True, there's no "wire" connecting the loops, but the queue construct is "unintuitive enough" to require a free label to explain its purpose.

 

Are there advantages of a queue over a local variable for stopping parallel loops?  I've also used Functional Global Variables (usually looking like a big red STOP sign, and placed on the Error line in each loop -- when one loop stops either because of an error or a True input to the "Global Stop" VI, it returns True, which is wired to the Stop terminal of all of the While loops in the VI.  If any loop stops, therefore, they all stop.

 

Bob Schor

0 Kudos
Message 1 of 21
(7,402 Views)

The disadvantages of a local variable is that you would have to have a boolean control on the front panel associated with it (and you'd probably want to hide it).  It would also have to be switch rather than latching action, and you'd have to reset the the boolean switch at the beginning of the VI, or right before it finishes.

 

The disadvantage of a functional global variable is that you'd have to have another subVI, and you'd have to initialize it at the beginning of the main VI.

 

With the queue, no front panel control needed and no extra subVI needed.

 

That said, I would never think to do it the way they did (I'm looking at Display VI.vi in the example finder.)  It just seems like a non-obvious solution to stopping the VI.  (Another programmer seeing that construction would have to pause for a few minutes to figure out what is really going on.)  I would just go with the local variable method (particularly if I want a stop method to be a front panel button) or more likely a FGV if I need to communicate the shutdown requirement to other VI's.  I would also issue a shutdown command into any queues so that while loops waiting for a command in the queue would finish up and stop.

 

If anything, seeing that done in an example teaches you one more way to go about stopping a VI if you ever need it.

0 Kudos
Message 2 of 21
(7,397 Views)

@BOB Schor wrote:

It seems slightly arcane to me to create a queue just for this purpose.  


 

Queues, notifiers, and events are the "correct" constructs to use for communicating between parallel threads on the same computer.  Using local variables to convey information is usually a convenient hack.  You can do it (and sometimes I do) but you might regret it later.

 

About a year ago and a half ago I was working on a large project that had been started by other developers.  The main vi had about 5 parallel loops, each with their own state machine using a number of local variables and property nodes.  Trying to step through code to debug it was nearly impossible, so I put 3 of the loops in sub vis.  Needless to say, sub vis and local variables don't play well together.  As I recall it took me a couple days to disentangle everything and implement a messaging system with the same functionality.

 

Lesson Learned:  Every shortcut taken incurs some amount of "code debt" that will have to paid off in the future--with interest.  As the debt grows (continuously using shortcuts) more effort is spent paying off interest (fighting the limitations of the shortcut) than paying down the principle (refactoring and improving the code) or saving for the future (killing bugs and adding new features.)

 

As a general rule all my local variables and fp property nodes go in the UI loop, and only in the UI loop.  If another loop needs to update a fp value, it sends the new value to the UI loop in a message and the UI loop handles the actual updating.  On the occasion where I do use local variable/prop nodes in other loops, I recognize it for what it is--an implementation shortcut that will probably have to be changed later.

 

 


@BOB Schor wrote:

Are there advantages of a queue over a local variable for stopping parallel loops?


 

In addition to the disadvantages Ravens listed and the limited ability to refactor code, there may be performance considerations.  I know using fp property nodes requires an internal switch to the UI thread (not to be confused with the UI loop on the bd) which requires considerable overhead.  I don't think local variables do, but I'm not sure.  Regardless, sending data directly to the terminal is faster than using a local variable.

 

If you use a local variable wired directly to the stop terminal then you have less control over the clean up process.  Sometimes a loop will have a fairly complex shut down process.  If one step fails you might want the program to alert the operator and continue functioning.  Once you exit the loop you can't go back.  Continuing the program is no longer an option.

 

Sometimes loops have to be shut down in a particular order.  Again, you can't control this very well using a local variable wired to a stop terminal, at least not without a gigantic flat sequence structure or error wires snaking back and forth.

 

Finally, usually there is some sort of information that needs to be transferred between loops.  "Stop" is just one of those pieces of information.  If you already have something in place for communication, why step outside that and use something else?

 

--------------

 

As far as the examples go, I'd view them as simplified code to illustrate how network streams work, not an example of how to build a robust application.  Typically if one loop unexpectedly exits all the loops should exit.  This safety valve helps prevent hung apps and unpredictable behavior.  The examples I looked at don't have that behavior.  (I don't expect them to either as that would unnecessarily complicate the code.)

Message 3 of 21
(7,353 Views)

I would use two loops and event structures to do this. A queue is a little overkill unless the program is going to expand a lot. Even with that events can easly handle this. See my example (very simple)

Tim
GHSP
0 Kudos
Message 4 of 21
(7,340 Views)

@aeastet wrote:

I would use two loops and event structures to do this...  See my example (very simple)


That approach might work for very simple vis such as the Network Stream examples, but as a general approach to handling multiple loops I strongly advise against it.  How do you plan on sending information between the two loops?  What do you do if the parallel loops are in a sub vi and the user isn't exposed to the front panel?

 


@aeastet wrote:

A queue is a little overkill unless the program is going to expand a lot.


Perhaps you work in a different environment than I do.  I don't have a single piece of software I've released that I know will not require changes in the future.  Customers think of all sorts of features to add after they've had the app for a while.  They become decidedly unhappy if I tell them I have to rebuild the architecture because the current implementation can't support what they want to do.

 

Queues are not difficult to use.  If you are venturing parallel programming using multiple vis it will be well worth your time to get familiar with them.

0 Kudos
Message 5 of 21
(7,307 Views)

THe event structure is very flexible. It can do anything that you want. I have this implemented on some very large multi loop programs. It is very easy to use and very flexible. I can talk to subvi using events and it is very scalable.

Tim
GHSP
0 Kudos
Message 6 of 21
(7,278 Views)

@aeastet wrote:

THe event structure is very flexible. It can do anything that you want.


 

It can't fire on a fp event generated by a different vi.  (And even if it could I would still claim it's not a good idea.)

 

I agree the event structure is very powerful, especially when it is used with user events.  My comment was directed at the way your example has multiple loops catching front panel events.  When loops are dependent on front panel controls explicitly via local variables or control references, or implicitly via an event structure, you no longer have the ability to move that loop into a sub vi and reuse it.  That bit of functional code is tied to that user interface.  Furthermore, as I mentioned earlier, you can't take that vi and use it as a sub vi since it requires a fp event to stop the loops.

 

One of the principles of software engineering is modularity.  It makes code much easier to understand, modify, and test when requirements change.  Your example limits the ability to modularize major functional aspects of the application.  In my experience the UI is the last area to get nailed down.  Users always want changes after they see the application in action.  Separating the UI's functional code from the application's functional code is high on my list of priorities.  That means keeping all references (implicit and explicit) to UI controls in loops dedicated to UI operations.  (I'll often have one loop to catch fp events and another loop to update indicators showing data, app state, etc.)  All other operations are delegated to functional modules via messages passed on queues, notifiers, or user events.

 

If that implementation meets your needs and the needs of your customers, great!  There's nothing wrong with using it.  But there are significant limitations to that implementation, and once you bump up against those limitations you'll have to spend a lot of time rewriting code to get around them.  There are solutions available for handling multiple loops that are much more flexible and much more scalable than using fp events.

0 Kudos
Message 7 of 21
(7,239 Views)

 


@Daklu wrote:

@aeastet wrote:

THe event structure is very flexible. It can do anything that you want.


 

It can't fire on a fp event generated by a different vi.  (And even if it could I would still claim it's not a good idea.)

 

I agree the event structure is very powerful, especially when it is used with user events.  My comment was directed at the way your example has multiple loops catching front panel events.  When loops are dependent on front panel controls explicitly via local variables or control references, or implicitly via an event structure, you no longer have the ability to move that loop into a sub vi and reuse it.  That bit of functional code is tied to that user interface.  Furthermore, as I mentioned earlier, you can't take that vi and use it as a sub vi since it requires a fp event to stop the loops.

 

One of the principles of software engineering is modularity.  It makes code much easier to understand, modify, and test when requirements change.  Your example limits the ability to modularize major functional aspects of the application.  In my experience the UI is the last area to get nailed down.  Users always want changes after they see the application in action.  Separating the UI's functional code from the application's functional code is high on my list of priorities.  That means keeping all references (implicit and explicit) to UI controls in loops dedicated to UI operations.  (I'll often have one loop to catch fp events and another loop to update indicators showing data, app state, etc.)  All other operations are delegated to functional modules via messages passed on queues, notifies, or user events.

 

If that implementation meets your needs and the needs of your customers, great!  There's nothing wrong with using it.  But there are significant limitations to that implementation, and once you bump up against those limitations you'll have to spend a lot of time rewriting code to get around them.  There are solutions available for handling multiple loops that are much more flexible and much more scalable than using fp events.


 

I use event structures in sub vi's al of the time. I don't seem to have any problems with the way they work. I guess that maybe you do not know the proper use of this tool and you think there is a limitation in the way it can be used. I can assure you that an event structure in a sub vi can be read and can send events back to the main vi. This is easy to do and very flexible. I have vary big applications the use modular code using this method and I have NEVER had a problem. You need to understand how this system works and use it properly to take advantage of the power.

 

Not only are you very wrong in the way you think events wok here but the event structure can be use to handle multi level events thrown by many different loops, vi's, sub vi's and even other applications. This seems very flexible and seems to me that if I can talk to it from anywhere that it is a system that can be modularized.

 

Do you know that you can register many different levels of events to the event structure? It is not just for button pushes, mouse up and down and drag event. Do you know that?

Tim
GHSP
0 Kudos
Message 8 of 21
(7,230 Views)

@aeastet wrote:

I can assure you that an event structure in a sub vi can be read and can send events back to the main vi. This is easy to do and very flexible.


 

Please post an example of an event structure in a sub vi handling a front panel event, such as a button press, on the calling vi.  I'm very interested in seeing it.

 

 


@aeastet wrote:

Do you know that you can register many different levels of events to the event structure? It is not just for button pushes, mouse up and down and drag event. Do you know that?


I'm not sure what you mean by "different levels of events," but I am aware that there are built-in events for more than just controls.  If you are referring to user events, then yes, I am very familiar with them too and have used them in my applications.  However, user events are a bit more difficult to work with (and have a different purpose) than queues, so based on your comment that "queues are a little overkill" I'll hazard a guess that you're not referring to user events.

0 Kudos
Message 9 of 21
(7,192 Views)

this was a fun little example to write.

 

the top level has a button.  it passes a reference to that button to a subvi.  the subvi registers for events from that reference, and handles them in event cases.  Basically it has some indicators that signal what it knows about the button.

 

The top level handles its own panel close? filter event, firing a user event that signals the subvi to quit.

 

-Barrett
CLD
Download All
0 Kudos
Message 10 of 21
(7,181 Views)