From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Advanced Architectures in LabVIEW course suggest incorrect solution to maintain QDMH message sequence

Solved!
Go to solution

In the LabVIEW Advanced Architecture online course there is a demonstration of a Queued Data Message Handler passing messages using a named queue between two different vi's. However the solution highlighted particularly as ensuring integrity of message sequence order is incorrect and may fail


The example (partly attached) has "Main - Process.vi" and "Main - interrupt Process.vi". Basically the intention is to demonstrate how the "Main - Process.vi" can be interrupted in its cycle when the interrupt messages can be received at any time.

 

In this - "Main - Process.vi"   the description says:
"Run this VI and run Main - Interrupt Process.vi. When you press the Interrupt Process button, it may interrupt the QDMH in this VI at any time. That could cause significant errors in the system. Messages coming in from another source, should be controlled in some manner."

 

In the "Main - Process - Protected.vi" which is claimed to solve this problem it says:
"Run this VI and run Main - Interrupt Process.vi. When you press the Interrupt Process button, the interruption is controlled and only happens between Process 3 and Process 1. Notice how the messages are queued at the same time in the Timeout case in this VI.
Also, consider writing a more intelligent block of code to intercept the messages coming in. "

 

Main -Process -Protected.vi incorrectly handling risk of messages being interleaved with other messagesMain -Process -Protected.vi incorrectly handling risk of messages being interleaved with other messages

Now - the claim that enqueuing all the three process messages at the same time will prevent the interrupt to slip between the process1 and process2 or process2 and process3 is incorrect.

 

The problem lies in the "QDMH POLY Enqueue Strings.vi" - the messages are actually just pulled out of the array of messages one at a time and enqueued one at a time. So there is no guarantee that some other process may not slide a message in between. It is easy to demonstrate just by putting a short wait in this array to queue loop inside "QDMH POLY Enqueue Strings.vi". This increases greatly the chance the interrupt message slips in between, but even without such wait the probability is finite.

Enqueue an array of strings is not atomicEnqueue an array of strings is not atomic

No need to say that such error can be difficult to locate as it likely will occur infrequently so must be dealt with at design stage.


I would assume that it can only be solved by using some sort of protecting semaphore in the enqueue vi or handled at the applications use of messages.


The JKI statemachine framework for instance does not have this problem because multiple messages are packed into one string and separated by new-lines and the enqueuing is atomic because it is only one string which is queued.

 

 

 

 

 

Message 1 of 10
(3,038 Views)

You could also solve it by not giving out the Queue reference via naming it...

A FGV around the Enqueue and a private Queue Ref would act like a semaphore (as you described) without preventing global enqueuing, in the case that you really want that functionality.


GCentral
0 Kudos
Message 2 of 10
(2,966 Views)

I don't have 2019 so could not look; is the "Interrupt Process button" in the same loop as the messages are enqueued?  Or does the interrupt button send a message to the loop doing the multi-message enqueue?  If so, that means that button cannot interrupt the set of messages, and either all are sent or none are sent.

 

If, instead, the interrupt message come from a third party to the loop receiving those messages, then there is a small but non zero chance (as you rightly point out) that the interrupt will come in between the enqueued messages and that is a serious flaw in the design.

0 Kudos
Message 3 of 10
(2,953 Views)

The interrupt sender is in another vi, started separately from the main process vi. So the messages are completely asynchornous.

 

0 Kudos
Message 4 of 10
(2,950 Views)

Got a  computer that has 2019 and had a closer look.  I would advise you treat this as just a classroom example and not something to actually study in detail.  Look at real-world designs actually used by their creators, such as the JKI statemachine you mentioned.  

0 Kudos
Message 5 of 10
(2,925 Views)

My goal with this post is primarily to point out that the online course "Advanced Architectures in LabVIEW" teaches an incorrect solution so this gets corrected. The course is from 2012.

 

 

0 Kudos
Message 6 of 10
(2,924 Views)

@drjdpowell wrote:

Got a  computer that has 2019 and had a closer look.  I would advise you treat this as just a classroom example and not something to actually study in detail.  Look at real-world designs actually used by their creators, such as the JKI statemachine you mentioned.  


I would agree with that, had it not been that the example specifically says that it solves this race problem - which it does not.

0 Kudos
Message 7 of 10
(2,923 Views)
Solution
Accepted by topic author heel

@heel wrote:

My goal with this post is primarily to point out that the online course "Advanced Architectures in LabVIEW" teaches an incorrect solution so this gets corrected. The course is from 2012.

 

 


A worthy goal.  I'm afraid there is a lot more wrong with that example than just what you are rightly pointing out.  I've given talks on designing and using queued message handlers, and I'll remember this next time as a good example of what not to do.

Message 8 of 10
(2,915 Views)

If the Enqueue function is non reentrant and it's the only one enqueing stuff it should be pretty safe. With a named queue it's easy to hack around through, so in this case it'd be better to use an unnamed one.

/Y

G# - Award winning reference based OOP for LV, for free! - Qestit VIPM GitHub

Qestit Systems
Certified-LabVIEW-Developer
0 Kudos
Message 9 of 10
(2,860 Views)

This is looking like a Queued State Machine (QSM) with the ability to let an outside force directly influence the state.  This should not be allowed!!!  QSMs should have exclusive control over the state queue.  There can be another queue or User Event for other loops to send information into this state machine.  So I see this as another reason not to use Named Queues.

 

In contrast, a Queued Message Handler (QMH) should have NO control over its state queue, not even to command itself to do something.  The only control it should have is whether the queue exists or not.  A QMH can retain some state to do something if a message does not come in (ie the Dequeue times out).  But any message coming in takes priority over anything the QMH is doing.


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
Message 10 of 10
(2,850 Views)