LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

How to avoid race condition in event loop?

Solved!
Go to solution

I'm having a race problem in event structures.  I've looked through various forum threads and haven't been able to track down a solution.

 

In the attached vi (labView2015), if you type in a new number for 'X', do not hit enter, and then hit the 'Go' button then the old value for 'X' is used in the event structure.  I infer that this is a race problem where having clicked on the 'Go' button has both initiated a task in the event structrue and also set up something in the queue to actually update the value of the variable.  That sounds right?

 

This is the simplest example I could make for this problem that has emerged in much larger, more complex vi.  All help much appreciated.

 

With thanks!  Devon

0 Kudos
Message 1 of 11
(4,868 Views)

... well this VI acts as it's supposed to. You hit Run on the VI, change the value, then hit Go. The program ready the X value, and writes to the Y value, then ends. I think what you're confused about is the fact that your code only runs a single time, so the second time you click, the code has already ended and will no longer trigger an event or anything.

 

Your title says "loop", but you didn't use a loop. The Event Structure is not a looping structure, it just handles events. You want something like this:

Go.png

Cheers


--------,       Unofficial Forum Rules and Guidelines                                           ,--------

          '---   >The shortest distance between two nodes is a straight wire>   ---'


Message 2 of 11
(4,860 Views)

Actually, in addition to require a loop around your Event structure, you should configure your event for the GO button for "Value Change" instead of "Mouse down".

Marc Dubois
0 Kudos
Message 3 of 11
(4,848 Views)
Solution
Accepted by easyXAFS

@MarcDub wrote:

Actually, in addition to require a loop around your Event structure, you should configure your event for the GO button for "Value Change" instead of "Mouse down".


I should have pointed this out, but I set my event in my snippet to Value Change.

Cheers


--------,       Unofficial Forum Rules and Guidelines                                           ,--------

          '---   >The shortest distance between two nodes is a straight wire>   ---'


0 Kudos
Message 4 of 11
(4,839 Views)

@MarcDub wrote:

Actually, in addition to require a loop around your Event structure, you should configure your event for the GO button for "Value Change" instead of "Mouse down".


 

So, if you had run the original code, you would notice the behavior he described:  The "Mouse Down" event triggered before the X value was updated.  This is understandable - mouse down event is what causes loss of key focus on X.  Loss of key focus on X is what causes the value of X to be updated.  SO, mouse down event triggerd on "Go" will cause the "previous" value of X to be used in the calculation because its value hasn't actually been updated yet.

Message 5 of 11
(4,833 Views)

Apologies, this happens when I am running that VI with 'continuous run' (the arrows pointing at each other) not 'one shot'.  In continuous run, you'll see the problem.

 

Well, any of the following seem to 'solve' the problem...

1) throw the whole thing into a while loop and use just 'run'.

or keep using 'run continuous' and:

2) change the event trigger to mouse up (a cheat that assumes that the thread execution is faster than even a video game player can click and unclick?)

3) change the event trigger to 'value change', although I need to sort out if that might get double-triggered depending on mechanical action (?).  There's a warning about latched booleans in the event definitions that I've never quite understood.

 

Thanks for the help James, I think I'm on one (or more) functioning tracks now.

 

Devon

 

 

 

0 Kudos
Message 6 of 11
(4,828 Views)

The value change event is what you pretty much always want to use in the instance of a button click. Set the button to be Latching (see the right-click options) so that it sets back to False once it's been triggered. This will only result in a single event trigger.

 

Now that you've mentioned the issue with run-continuously, I can clarify that too. Since you are using the Mouse Down event, the event actually triggers before the X input is "deselected". I say "deselected", because the value of a control isn't updated until it is deselected. This occurs when you click outside the control, or press enter, etc. So your error only occurs when you click directly on the botton immediately after changing X without clicking elsewhere, or pressing enter (like you said). You are forcing a race condition between the value change of the control and the Mouse Down event. Although, I wouldn't necessarily call it a race condition, because the mouse down event will always occur first as that's the event that triggers the X control value change.

 

That all being said, don't use the run-continuous button in real applications. It should only be used when you are toying with input values to see what works best in your subVI.

 

Edit: Oops, I didn't see Bowen's reply before typing this up.

Cheers


--------,       Unofficial Forum Rules and Guidelines                                           ,--------

          '---   >The shortest distance between two nodes is a straight wire>   ---'


Message 7 of 11
(4,817 Views)

@James.M wrote:

The value change event is what you pretty much always want to use in the instance of a button click. Set the button to be Latching (see the right-click options) so that it sets back to False once it's been triggered. This will only result in a single event trigger.



 

Let's clarify that paragraph a bit.  The boolean will reset back to False once the terminal has been read.  For that reason, you want to place the terminal for the boolean inside the value change event case for that control.  Pressing the button will trigger the event.  When the event structure gets into the path of execution, that value change event that was triggered will now be handled.  The terminal will be read (even if you don't do anything else with it.)  LabVIEW's latch action will then cause the boolean to "pop out" and return back to its original state and will not fire a secondary event.

 

(Now if you use switch action buttons, events will fire on both the false to true, and true to false value changes.)

Message 8 of 11
(4,810 Views)
Actually, there is a race condition/bug associated with reading numeric inputs. The underlying problem is that there are two buffers: one for the front panel (which is what you type into) and one for the block diagram. The block diagram buffer gets updated when the numeric control loses key focus.

Unfortunately, some actions will cause things to happen without causing the numeric control to lose focus, with the result that the front panel buffer isn't copied to the block diagram buffer. Things like key navigation and clicking buttons.

There can be other related problems as well. Depending on how your code is written there are several ways of working around these issues.

Mike...

Certified Professional Instructor
Certified LabVIEW Architect
LabVIEW Champion

"... after all, He's not a tame lion..."

For help with grief and grieving.
Message 9 of 11
(4,745 Views)

@easyXAFS wrote:

 

1) throw the whole thing into a while loop and use just 'run'.

or keep using 'run continuous'


Some side notes:

 

  • Under most circumstances, "Run Continuously" cooks your CPU. Don't do it!
  • Under most circumstances, running a while loop without a "wait" cooks your CPU. Remember the wait node!
  • In this particular case, your CPU was saved by the fact that the event node forces your code to wait.
Certified LabVIEW Developer
0 Kudos
Message 10 of 11
(4,614 Views)