LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Race condition using event structure

Solved!
Go to solution

Hi

Tried to add a simple way to display "real time" serial data in a string indicator in a project, using a value signaling property and a event structure.

The event structure is to slow to execute/read the string text added by the Val(Sgnl) property(numbers of triggered events are correct).
Have i messed up somewhere or is this race condition expected(should i have used Queues instead)?

 

 

/J

 

 

0 Kudos
Message 1 of 10
(4,560 Views)

Your timeout event is not used, why is it there? events are primarily for user interactions. Abusing them for data communications seems wrong. Your VI also cannot be stopped while the lower FOR loop is still running.

 

I'll have a look at it later.

0 Kudos
Message 2 of 10
(4,538 Views)
Solution
Accepted by topic author std

In your event loop you're just using the reference to the control to get the value.  Stop using that, and start using the "NewVal" terminal from the event (it's currently hidden, you need to expand your event variables or change one of the existing ones to it). 

 

New value.png

Because the lower loop runs at a higher speed than the upper event loop, the events are reading future data, effectively.  The "CtlRef" terminal there is not frozen in time, it updates with everything else.

 

I do agree with Altenbach that in this situation the event structure is being abused a bit here.  While events can sometimes be the best solution for data communication under certain specific circumstances (I'm thinking of a situation with multiple unknown parallel processes that need to receive lossless information sent to them, not exactly a common occurrence) , in this one it seems to be there just to avoid making a queue.

0 Kudos
Message 3 of 10
(4,530 Views)

As already hinted, your code is a prime example of "the tail wagging the dog".

 

If you want the Com value that triggered the event, read the "new value" from the event data node. Using a reference to read the value will give you the current value of the control, not the value that triggered the current event. The lower loop spins so fast that the events get queued up in the event queue and then.

 

There is nothing wrong in the way it functions with a very short wait in the lower loop.

 

However, you need to re-think your architecture. It's backwards.

 

 

0 Kudos
Message 4 of 10
(4,519 Views)
Solution
Accepted by topic author std

Some repeats here, but here are a list of things I found wrong:

1. No need to close an explicit reference to a front panel item.  It will be closed with the front panel.  Even when you try to close the control's reference, nothing will happen (it is literally a no-op).

2. Delete the Timeout event case.

3. Use User Events to send messages to your GUI loop.  This will decouple your UI from the process since you just need a reference to the event instead of the actual control/indicator.  Let the GUI loop decide what to do with the data.

4. No need for your sequence structures since data flow of the error cluster will force the sequence of functions.

5. You Done button really should be set to the Latch When Released mechanical action.  This can be done when you no longer need the reference.

 

Attached is a non-cleaned up version of your VI using User Events.


GCentral
There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines
"Not that we are sufficient in ourselves to claim anything as coming from us, but our sufficiency is from God" - 2 Corinthians 3:5
0 Kudos
Message 5 of 10
(4,512 Views)
Solution
Accepted by topic author std

Just a few more comments:

 

  1. Wiring the FALSE to the event structure is irrelevant for execution order, because writing to the local variable is after the wire branch and thus still executes in parallel to the event loop. It does not matter here, but could give you race conditions elsewhere.
  2. None of your sequences are needed. If you want to delay the start of the lower loop, just wire the output of the wait function to the loop boundary. Don't use sequence structures to delineate code sections cosmetically.
  3. Closing a direct reference ("Com" after the upper loop) does nothing, so don't do that. (details)

 

In summary, use the event structure for user interactions and use e.g. queues to communicate data between code sections if needed.

0 Kudos
Message 6 of 10
(4,511 Views)

Tim and me think alike and at the same exact time (10:17). 😄

0 Kudos
Message 7 of 10
(4,508 Views)

@altenbach wrote:

Tim and me think alike and at the same exact time (10:17). 😄


Well, I was delayed a good 5 minutes due to my 3-year-old insisting I play with him instead of doing my work.  If it wasn't for Icemaggedon (rain changing to sleet/freezing rain changing to snow), I would actually be at work and would have been a lot faster.


GCentral
There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines
"Not that we are sufficient in ourselves to claim anything as coming from us, but our sufficiency is from God" - 2 Corinthians 3:5
0 Kudos
Message 8 of 10
(4,499 Views)

After my initial post, I had to run for the bus and only had phone access. One hour right there. 😄

 

 

0 Kudos
Message 9 of 10
(4,495 Views)

Thank you all for sharing your knowledge and pointing out what i missed.

I'm sorry that I was unclear that VI i posted is just a cut down part of the original VI (a ProducerConsumerEvents vi) to zoom in on the problem. So the "ms wait VI" in the timeout case for example is just something i forgot to delet after trying to find out where things went wrong.

 

/J

0 Kudos
Message 10 of 10
(4,432 Views)