LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Release Queue error 1

Hello everybody,

 

I have developed a Producer/Consumer architecture (using queues) in order to acquire data from a spectrum recorder instrument.

 

The VI is working well, as expected, but I need to acquire data during a very long time (for example 8 hours). For this reason I added a "Time control" into a´n external While loop: if the stop time is < actual time stamp, I repeat the complete acquisition.......

 

All is fine, but at certain times I get the error 1 "Release Queue" (see attachment)....I don't understand why, because I followed the instructions in order to use queue functions, and each queue (I have 2 queues, 1for frequency, and 1 for level) is relöeased at the end of each acquisition.

 

How can I avoid this error ?

 

Thanks for your help.

Paola.

0 Kudos
Message 1 of 7
(3,556 Views)

Paola,

 

you really do have a huge monitor, do you?

Looking into the VI (which should be cleaned up for less wire bends and SIZE!), i see that you do not use proper error handling. Which release queue function creates the error?

  1. Why does the consumer loop not stop if you "kill" the queue? (Hint: Use error handling to stop the consumer)
  2. Why do you use two separate queues if each queue is written in ONE single producer loop and read in THE SAME SINGLE consumer loop? This seems to be a mis-concept....
  3. Do not use "Build Array" inside of while loops, esp. if termination of these loops is obfuscated.
  4. The event structure covering the complete code is nonsense. Remove it or move it INTO the loop.
  5. Keep references and error cluster in shift registers within loops.
  6. Insert some timing in your producer loop as it polls data.
  7. Implement a proper state machine as master architecture to structure your code in a well readable way.
  8. The global variable could induce race conditions. Try to remove it.

 

Issue 5 is creating the error. I assume that the error occurs ALWAYS.

You create a queue, flush it (no elements in it). The you are using this amount of flushed elements (0) to feed a for-loop enqueuing elements. This loop never executes. As you pass the queue reference in tunnels (instead of shift register), you delete your queue reference. The you try to release a NULL queue, which naturally has to throw an error!

 

These are just my 8 cents, hope they help,

Norbert

 

Norbert
----------------------------------------------------------------------------------------------------
CEO: What exactly is stopping us from doing this?
Expert: Geometry
Marketing Manager: Just ignore it.
Message 2 of 7
(3,549 Views)

Hi Norbert,

 

first of all thank you for your answer. I'm quite new in Labview, and it's only 2 months that I'm programming with it ... Of course, I agree with you, ths VI should be cleaned at least for the visualization !

 

  • Why does the consumer loop not stop if you "kill" the queue? (Hint: Use error handling to stop the consumer) -> how can I do that ? looking at the example from NI for Producer/Consumer, I saw that the queue is only released at the producer side, and the Consumer runs indipendently....

 

  • Why do you use two separate queues if each queue is written in ONE single producer loop and read in THE SAME SINGLE consumer loop? This seems to be a mis-concept.... --> one queue is for the frequency data, and another is for the level data, and the acquisition from the instrument does not allow to acquire these data together....so I think I'm oblioged to use 2 queues.

 

  • Do not use "Build Array" inside of while loops, esp. if termination of these loops is obfuscated.  -> I need to append data during one acquisition, and to copy them only at the end, into one file.....if there is a better solution to do that, please tell me.

 

  • The event structure covering the complete code is nonsense. Remove it or move it INTO the loop. -> the event structure is necessary because I want to program the time into which the VI has to start (maybe also during nigth)...

 

  • Keep references and error cluster in shift registers within loops. --> ok, I did it and I'm running the code to see if I get the same error.  In fact, I did like this (see attachments)...is it correct ?

 

  • Insert some timing in your producer loop as it polls data. --> do you  mean for example a wait function ?

 

  • Implement a proper state machine as master architecture to structure your code in a well readable way. --> I should do that, but I have to understand how to implement it ...... this will be the next evolution I guess, but for the moment, this is all I was able to do !

 

  • The global variable could induce race conditions. Try to remove it. --> which global variable are you talking about ? Sorry 🙂

 

Thank you for your help.

Paola

0 Kudos
Message 3 of 7
(3,536 Views)

Paola,

 

if you look into the producer/consumer template provided by LV, you will see that the consumer loop terminal is connected to the error cluster. In case an error occurs during waiting for dequeue (as e.g. the queue is released by the producer), the "dequeue" function will throw an error which terminates the consumer as well.

 

Use a single queue as 1:1 data flow from one producer to ONE consumer. If data consists of more than a single data type, use clusters or variant data type for the queue (bundle and unbundle "by name")

 

You have to limit the maximum available/provided memory. Using the concept of a "ring buffer" fits to most applications in that case. Pre-allocate an array with the "buffer size" and then replace single elements/blocks using "replace array subset". Most likely, you will have to handle your own "write index" (aka. "write pointer"). If data really grows unlimited, using log files is the only appropriate answer.

 

You could use a wait function and wire the output "millisecond timer value" to the outest loop instead of using a timeout event encapsulating your complete code. Using statemachine, you would start with an "initialize" state containing that simple wait.

 

Yes, you understood that hint with shift register correctly for the while loop. Still, you missed it for the two for-loops in the producer. THESE are the offending code pieces...... (so you will still get the error!)

 

Yes. If you need maximum execution performance, you still contain a wait function, configured for '0' ms. This makes sure that the compiled code behaves more "cooperative" than with leaving the waiting out of the code.

 

I was talking about the global called "Session Data".

 

Norbert

 

 

 

Norbert
----------------------------------------------------------------------------------------------------
CEO: What exactly is stopping us from doing this?
Expert: Geometry
Marketing Manager: Just ignore it.
0 Kudos
Message 4 of 7
(3,528 Views)

The big issue I see in there is that you are not creating your queues.  You have them setup to NOT create if not found.  Remove those FALSE booleans to the Obtain Queues.  And you also have a wire going from the consumer loop to the producer loop.  How is that even working?  You must be looking for a value of 0 or else you would be stuck in an endless loop.


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 5 of 7
(3,512 Views)

@crossrulz wrote:

[...] You have them setup to NOT create if not found.  Remove those FALSE booleans to the Obtain Queues.  And you also have a wire going from the consumer loop to the producer loop.  [...]


Wow, nice catch....must have overlooked this 😞

 

Norbert

Norbert
----------------------------------------------------------------------------------------------------
CEO: What exactly is stopping us from doing this?
Expert: Geometry
Marketing Manager: Just ignore it.
0 Kudos
Message 6 of 7
(3,507 Views)

Hi,

 

yes, you are rigth. I removed the enqueue function in the for loop, and it is still working in fact......I'm checking and trying to improve this structure.

 

The False boolean have been already there (since I'm using some functions prepared by the supplier of the device) and I left them like this......even if I agree with you, they should be TRUE. Anyway, it is working like this, even with FALSE boolean. I will have a look on this also.

 

Thanks!

Paola

0 Kudos
Message 7 of 7
(3,505 Views)