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: 

Product Consumer Loop Losing Data After Releasing Queue

The producer consumer loop is a nice structure.  However, if the producer loop stops and then the queue is destroyed by the release queue function the consumer loop will error out and the last data on the queue from the consumer will never be enqueued by the consumer loop.  This data will be lost.

 

What is the best way to prevent this from happening?

 

Thanks!

0 Kudos
Message 1 of 10
(2,981 Views)

Yes.  Data flows from Producer to Consumer, so the "Stop" signal should also flow from Producer to Consumer.  One way to do this is to send a "Sentinel", a signal that says "I'm done".  Here's an illustration:

  • Assume the Queue element is an Array of Dbl (say, the acquired data from a DAQ device).
  • The Producer enqueues Arrays of data and happily sends them to the Consumer.
  • At some point, the Producer "knows" it is time to stop.  It sends an empty Array (the Sentinel) to the Consumer and simply exits, leaving the Queue intact.
  • The Consumer takes elements off the Queue (with or without a TimeOut).  If the contents are an Empty Array, then the Consumer "knows" that the Producer has sent its last data, so the Consumer exits, and the Consumer destroys the Queue.  Otherwise, the Consumer "consumes" (or otherwise processes) the Data.

LabVIEW 2015 (in hidden form) and LabVIEW 2016 introduced Channel Wires, with the Stream Channel acting much like a Queue.  Sentinels are directly implemented in the Stream Channel by having a "Last Element" Boolean input on the Channel Writer and a similar Last Element? output on the Channel Reader, allowing the Producer (with the Writer) to signal the Consumer (with the Reader) that the Producer won't be sending any more data, so the Consumer can act appropriately.

 

Bob Schor

Message 2 of 10
(2,973 Views)

Bob,
Thanks for your quick reply. I unfortunately have LabVIEW 2013 so sentinels are not included.

 

Basically what I am trying to do is the following:
I have one loop (Loop 1) that runs and waits on a boolean response based on criteria to stop.
I have another loop (Loop 2) that runs in parallel that keeps track of test time (timer).
When Loop 1 boolean response = TRUE, Loop 1 should stop and also tell Loop 2 to stop.

I am using Queues for this for parallel loops because I am trying to not have to use a local variable.

Please see the attached code simple example.  Is this the best way to handle what I am trying to do?

 

Thanks!

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

What is the point of the queue?  You are putting booleans into the queue, but aren't ever using the data when you dequeue it.

 

You do NOT want the Release Queue happening when the producer ends.  That is why you have the problem of losing data.  You want to release the queue after the consumer ends.  That is way the consumer has had a chance to process all of the elements (which it isn't processing any in your example.)  It is a bad idea to use the error wire as a method to tell the consumer loop when to stop.  The "stop value" or command that you send through the queue should tell the consumer when to stop.

Message 4 of 10
(2,927 Views)

For one, you don't appear to be using the data that was enqueued in the consumer loop. Also, you can wire your code so that the queue is not release until both loops have actually stopped. However to do this you will need to use actual messages in your queue rather than a simple boolean value. The producer should send message to the consumer and the consumer will process the messages accordingly. One of the messages is a Stop message.


Given your current code though it appears you are only using the queue's existence to determine if you should continue running or not. This code doesn't make a lot of sense and I don't see where losing data would be an issue. You aren't even using the data from the queue. For items like an elapsed timer display I would generally use an event structure with a timeout event. Then you can have user events which will start, stop and reset the timer. In addition you can have an exit event which exits the loop.



Mark Yedinak
Certified LabVIEW Architect
LabVIEW Champion

"Does anyone know where the love of God goes when the waves turn the minutes to hours?"
Wreck of the Edmund Fitzgerald - Gordon Lightfoot
Message 5 of 10
(2,919 Views)

Ravensfan,

 

Thanks for the quick reply.  That all makes sense to me know.  I was trying to use the producer-consumer template that labview provides and took the structure as golden (i.e. used the error wire to shut down the consumer).  I am now using the queued boolean and sending it to the consumer and using that to shutdown the consumer loop.  This method works great.

 

In your opinion, for my application (1 loop running code other loop timing the running code loop) am I best suited to use queues?  Or is there another preferred method?  I am trying to do it the right way.

 

Thanks!

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

@testdesign wrote:

Bob,
Thanks for your quick reply. I unfortunately have LabVIEW 2013 so sentinels are not included.  Sorry that I wasn't sufficiently clear -- a "Sentinel" is just a unique value reserved for "The Queue is Finished".  In the case of a Queue of a single Boolean, this could work if you reserve, say, "True" for "Queue is finished" and "False" for "Queue is Valid".  This is basically what you are doing, but it really doesn't make sense.

 


A Queue is used to pass data from Producer to Consumer.  You aren't doing this, as you don't use the values on the Queue.  Rather, you are using the Queue to send a signal "Hey, I put something on the Queue, so do something now, ignoring what I put on the Queue".

 

What you have created is much closer to what LabVIEW calls a "Notifier".  Look it up.

 

But, as it turns out, you can turn this into a "Queue with Sentinel".  Do the following:

  • Replace the Shift Register in the top (Producer) loop with a simple Tunnel In, and don't pass the Queue out of the loop.
  • Get rid of the Release Queue.
  • In the Consumer loop, wire the element out (a Boolean) to the Case input (instead of the Error Line).  When the Queue element is False, you want to execute the code shown in your Consumer loop.  When the Queue element (the Sentinel) is True, wire it to the While's Stop Indicator to stop the Consumer.
  • In the Consumer, bring the Queue out from the Dequeue function to an output tunnel (you do not need a Shift Register for Queues) and wire it to the Release Queue function.

Bob Schor

 

Message 7 of 10
(2,912 Views)

@testdesign wrote:

In your opinion, for my application (1 loop running code other loop timing the running code loop) am I best suited to use queues?


Can you elaborate on this some more?  If you are just timing based on time, I do not see the point of another loop (just use the Elasped Time or Wait Until Next ms Multiple).  If you are timing based on a digital line, you can often do this in the hardware setup.


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 8 of 10
(2,900 Views)

@testdesign wrote:

In your opinion, for my application (1 loop running code other loop timing the running code loop) am I best suited to use queues?  Or is there another preferred method?  I am trying to do it the right way.

 


I should probably let Ravensfan answer this (as you asked him), but you might consider a Notifier.  It behaves a little differently than a Queue, so do some studying (read the Help, look at examples, etc.) and decide for yourself.  I will say that your (mis?)-use of a Queue in this situation was certainly a novel idea ...

 

Bob Schor

Message 9 of 10
(2,896 Views)

I was away eating lunch while the thread continued, but yes, I would have suggested a notifier as well.

Message 10 of 10
(2,882 Views)