LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Producer/Consumer Best Practice

Solved!
Go to solution

So I have been using LabVIEW for a few years now and still have a relatively simple question. I have posted three examples below and am wondering what is the best practice when it comes to using the Producer/Consumer with a Message Queue architecture. My gut tells me to always do it like Example 3, but I don't know why exactly. Maybe they are all the same until you get to a certain level of complexity. Any documentation you can point me to is much appreciated.

 

EXAMPLE 1 - Control Outside Event Structure, passing message only and use the control to update the indicator. 

 

Example1.PNG

EXAMPLE 2 - Control INSIDE Event Structure, still only passing a message and updating with Local Variable.
Example2.PNG

EXAMPLE 2 - Control INSIDE Event Structure, Passing message AND value from Control, unpacking it inside the consumer loop to update the indicator.

Example3.PNG

0 Kudos
Message 1 of 8
(2,446 Views)

If your use case is as simple as you are showing, then it probably doesn't matter. However, I would use a single loop, because updating an indicator is so fast that it doesn't really steal much time away to go to a specific case just to update it.

 

In general though, I would make a message handling loop look the most like ex. 3. The reason is that in the first 2 examples, the indicator is linked to the control. In the third example, you could send a message from anywhere. If you go through the trouble to make a nice message handling loop that talks to a piece of hardware or does some data processing, you want to be able to use it in another application with relatively little effort, and decoupling it from specific controls will help do that.

Message 2 of 8
(2,433 Views)

I use example #3 BUT not the dynamic data.

 

Using dynamic data makes no sense when you know your data is always a double numeric.

(In fact I have never found a use for Dynamic Data at all, as I always know what type of data I am collecting) 

 

I make a cluster that uses the proper data types for the data I am queueing, then a simple "unbundle by name" is all I need to separate the dequeued data.

========================
=== Engineer Ambiguously ===
========================
Message 3 of 8
(2,419 Views)
Solution
Accepted by topic author rkmadse

I would also nearly always pick #3.  One of the questions you need to ask is what you want to happen if the value changes twice in a row while the consumer loop is busy on another task.  Which do you want to happen?

 

1. The consumer case runs twice with the second value 

2. The consumer case runs once with the second value

3. The consumer case runs twice, once with the first value and once with the second 

 

Option 1 is what examples 1 and 2 give you.  Option 3 is what example 3 gives you. 

 

Option 2 isn't shown as a possibility but would involve writing a bunch of code that looks ahead in the queue for elements with the same instruction but different data, or checks the current value against the last one with a feedback node and skips execution if a match is found.

Message 4 of 8
(2,416 Views)

@RTSLVU wrote:

I use example #3 BUT not the dynamic data.

 

Using dynamic data makes no sense when you know your data is always a double numeric.

(In fact I have never found a use for Dynamic Data at all, as I always know what type of data I am collecting) 

 

I make a cluster that uses the proper data types for the data I am queueing, then a simple "unbundle by name" is all I need to separate the dequeued data.


That is not dynamic data, that is a variant. You still have to know what type of data it is (otherwise the variant to data will throw an error). The use case is when there is another case that updates a different kind of data, for instance a string. You can send a message with a different command along with the string data to update the string indicator. The alternatives would be a separate queue for each indicator, or updating every indicator whenever one piece of data changes.

Message 5 of 8
(2,398 Views)

Kyle brings up a very good point, you do not want the value of the control when the bottom loops runs, you want the value when the event is triggered, and the only way to ensure that is to enqueue the data. With the event structure you probably don't have to worry about that because you'd have to be clicking ridiculously fast, but for a real application that could enqueue a burst of data to consume, you definitely want the data to be enqueued.

Message 6 of 8
(2,396 Views)
Solution
Accepted by topic author rkmadse

1. What you have here is NOT a Producer/Consumer.  It is a Queued Message Handler.  A P/C is to process a stream of the same data type for processing or data saving.  A QMH is an asynchronous loop that accepts messages and reacts to said messages.  Slight differences, but important for most discussions.

 

2. One of the points of a QMH is the lack of coupling between the QMH and whoever is sending the messages.  So the QMH should not have anything that directly ties it to the sender.  Therefore, 3 is the closest to what you should do.

 

3. You have to be very careful about reference life time.  If the VI that created the queue goes out of memory, so does the queue.  This is a common way that your references become invalid.  So in the case of the QMH, the QMH should maintain the queue.  So it should create the queue and also close it.  I prefer closing inside the "Stop" case of the QMH loop.  This works since it won't be accepting any more messages, so it is fine for senders to get an error stating it is gone.  The other thing I like to do is wrap my queue reference in an Action Engine that is then set to be private inside of a library (lvlib).  I then have public methods that senders can use to actually send the messages.  These methods will bundle up all the data and write to the queue.  This keeps the senders from needing to know what is happening inside.  They just know they are sending X message with Y data in it.


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

Excellent information, thank you so much for taking the time!!!!

0 Kudos
Message 8 of 8
(2,306 Views)