LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Simultaneous event handling in Labview

I'm playing around with the idea of what ways can I run processes in parallel and wondering how others have done this, specifically in a UI  (example 5 buttons on the front panel, each trigger tasks that can take multiple minutes to complete and all 5 can be triggered at any time without waiting for the previous task to complete. 

 

A producer consumer structure works great to keep the UI responsive and queues up all button clicks to eventually be handled, but its still only in series.  If a consumer takes a long time to complete, we are still sitting there waiting until it is finished before moving onto handling the event for the next button clicked. 

 

I checked out  (http://www.ni.com/example/31009/en/) [ running multiple events simultaneously within LabVIEW]. and though this works, I feel there must be a more elegant way.... This example calls the "run VI" invoke method and sets the wait until done to false allowing the top level loop to keep running while the sub VI works on the side.

 

The more specific problem that sparked this was how I'm currently handling my "stop" case in some of my programs using a global stop flag.  So if I have a parallel loop running on the side, one of the cases that can stop the loop is a global boolean.  But this feels hacky and to make it stop an already running consumer case, I need to put in many individual checks to look at the flag in each sub vi.  So ultimately my program is left vulnerable to getting stuck in the consumer loop.

 

 

 

Message 1 of 4
(2,730 Views)

@Tim30 wrote:

I feel there must be a more elegant way.... This example calls the "run VI" invoke method and sets the wait until done to false allowing the top level loop to keep running while the sub VI works on the side. 

 


What do you consider inelegant about this?

 


@Tim30 wrote:

 

The more specific problem that sparked this was how I'm currently handling my "stop" case in some of my programs using a global stop flag.  So if I have a parallel loop running on the side, one of the cases that can stop the loop is a global boolean.  But this feels hacky and to make it stop an already running consumer case, I need to put in many individual checks to look at the flag in each sub vi.  So ultimately my program is left vulnerable to getting stuck in the consumer loop. 


You could disable the stop button unless all parallel tasks are completed. A simple boolean operation on the comparison wires in the upper loop of the example would do the trick.

 

You would need a global or similar mechanism  if the parallel  subVIs need to listen and react to a stop condition.

 

Also note that the quoted example is overly complicated. All it needs is place the terminal of the stop button in the upper loop, wired directly to the loop condition, and have a TRUE constant in the stop event of the lower loop. Now the button can be latch action and no local variables are needed at all. Also, the timeout event can be removed because it does not do anything useful.

0 Kudos
Message 2 of 4
(2,715 Views)

Another method that I prefer to the "Run VI" method is the "Start Asynchronous Call" method, which starts a sub-VI running (passing in parameters if necessary) and then it runs asynchronously, without further interaction with the calling routine.  It takes a tiny fraction of a second (I've not timed it, but it's pretty trivial) to start such a task, and then the main routine is ready for whatever else it needs to do.

 

When I've done this, I've usually built in a way to pass messages in and/or out of these parallel loops.  One way is via Notifiers or Queues (you could have a "Queue Listener" that does something if there's an input, otherwise it times out and possibly tries again), which (a) lets the Host tell everyone to "Stop now", and (b) lets the detached Loop tell the Host "I'm done".  It depends on what you want to do.

 

Bob Schor

Message 3 of 4
(2,684 Views)

@Tim30Tim30  wrote :

 

A producer consumer structure works great to keep the UI responsive and queues up all button clicks to eventually be handled, but its still only in series.  If a consumer takes a long time to complete, we are still sitting there waiting until it is finished before moving onto handling the event for the next button clicked.  


For me there isn't any problem for a Producer-Consumer structure to execute the code for all your button clicks at the same time. You just have a create one consumer loop for each button task. See the quick exemple attached below (LabVIEW 2016).

0 Kudos
Message 4 of 4
(2,651 Views)