LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

What if multiple consumers - which SW architecture should I use?

Solved!
Go to solution

There are several VI templates and documentation about producer/consumer type aqrchitectures

 

I have some experience with LV but limited experience with events and multi-threading programming.

My question is what if the consumer also produces data? ... the tutorials do not really extend to this.

In my application I have 3 USB CAN transcievers and a NI DAQ.

 

I intend to have multiple loops or threads for each hardware device at the lower level.

There will be a UI loop (producer) and a "test step sequencer" interpreting the front panel activity and sending commands to the hardware devices to take action or perform a measurement. 

 

My main problem is - what is the best method/practice of passing data back to the "test step sequencer" from the hardware after acquisition is complete?

 

Do you use the same queue to pass the data back (for analysis and test pass/fail evaluation) or some other method.

 

 

0 Kudos
Message 1 of 8
(3,763 Views)

Is the sequencer and UI loop the same?  Is it using an Event Structure?  If so, dynamic events work well.  Otherwise, I recommend 1 queue for each 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
0 Kudos
Message 2 of 8
(3,731 Views)
If you are feeling adventurous you might want to check out the Actor Framework. Do a search on decibel.ni.com.
=====================
LabVIEW 2012


0 Kudos
Message 3 of 8
(3,727 Views)

Forgive me for sounding amateurish but I have to ask....

 

Are queues supposed to have one one source of data or many, I know there wouldn't really be any problems with one producer and many consumers?

 

Supposing I have two asynchronous loops... one for "program control/UI etc." and another for "data acquisition DAQ."

Can I use the same queue, to pass configuration/commands both from  "program control loop" to "DAQ loop" and then after all data is obtained pass results back from "DAQ loop" to "program control loop"?

 

It might just be me, but it sounds risky if two seperate loops were able to put data into a queue. What if both loops are looking for the "dequeue element" VI at the same time. If one loop adds en element to the queue then immediately goes into a state waiting for a new element to be added to the queue it might read its own data? I suppose that this could be solved programattically in software.

 

I am just trying to find the simplest and most reliable way of passing data back and forth between loops/threads?? 

 

Thanks 

0 Kudos
Message 4 of 8
(3,696 Views)

@sammy346 wrote:

 

Are queues supposed to have one one source of data or many, I know there wouldn't really be any problems with one producer and many consumers?

 



I think your understanding of how queues work is backwards.

 

Queues are for a one to one, or a many to one relationship.  They don't work well for one to many relationship.  If you had multiple consumer loops trying to dequeue from a single queue, then those loops are going to constantly battle over who gets what queue element.  One loop will get the data, the others are not going to get it and will sit there waiting until the stars line up just right and they get a chance to steal an element out of the queue.  It is completely unpredictable error.

 

Many producers work just fine.  Just think of having multiple bosses each of whom throw work into your inbox.  You are going to work on each one's jobs one at a time based on the order they give them to you.

 

Notifiers are actually a better choice for a one to one or a one to many relationship.  It is like sending a broadcast message out and one or many places are just sitting there waiting to receive the message.  But notifiers don't have the ability to store multiple messages in order.

 

But what you are asking for is actually a bit different.  Your looking to get data back to the producer loop.  You could have two different queues.  One where the producer sends data to the consumer, and another where the consumer sends it back to the producer.  But there could be issues that each one winds up waiting for the other to send a message.

 

One thing you can do is what I think of as a "self addressed stamped envelope" system.  Suppose you have multiple producers that need to send data to a consumer for processing.  But the consumer loop needs to send the results back to the particular loop that sent it.  You could bundle a notifier reference in each queue element (a cluster of the data and a reference).  The consumer gets the element, unbundles and processes the data, and unbundles the notifier reference (each producer has its own) to know which producer to send the data back to.

 

See Array of variable-length lists in Action Engine

VIT References and missing queue commands

Message 5 of 8
(3,690 Views)
A queue can have multiple sources but only one dequeue. For multiple loops I like to give each loop its own input queue and its own output queue.
=====================
LabVIEW 2012


0 Kudos
Message 6 of 8
(3,689 Views)

So how does this sound...

 

I use a notifier system for the "main controlling loop" to broadcast messages to all my independant hardware devices (each with its own thread). The notifier message can be an enum + variant so that each device can determine whether the message is addressed to it, then keep or discard the contents (which will be the setup parameters for that test step).

 

Then I will use a queue system with all the hardware devices connected as a producers and the consumer is the "main controlling loop" it can wait till all the test results have returned, then initiate the next step with another notifier broadcast.

 

???

 

 

0 Kudos
Message 7 of 8
(3,680 Views)
Solution
Accepted by topic author sammy346

That might work.

 

One difference between notifiers and queues is that with queues, you can guarantee that the consumer loop gets the message (assuming there were no problems with the producer generating and sending it).  Even if the consumer is busy doing other things, the message will wait in the consumer's "inbox" until it is ready to read it.

 

With a notifier, there is no guarantee that every piece of code that waits on a notification will get all the messages.  Think of the notifier as a white board.  A message gets put on there for everyone who is interested to read it.  But when a new message is to be sent, the sender comes in, erases the board and writes the new message.  If someone who is interested in the messages has been busy and can't get to the board while the first message is there, it will never see the message.

 

If you want to guarantee that every loop gets all of their messages, then just have one queue for each loop that behaves as an inbox.  If you need to send the same message to multiple loops, then enqueue that data in multiple queues.  If you need to get a message back, then enqueue the sending loops queue reference in the data (the self addressed stamped envelope).  (you could also put a boolean in the cluster that could be a flag as to whether the 2nd loop needs to send something back or not.)  If you need the first loop to wait to get the data back before moving on, then it will wait on the queue.  But you may want to use the timeout function so that it doesn't wait forever for something that never comes back, and incorporate some logic in your program so that it can handle that situation (e.g. do nothing, send the message again, log or display an error message, ...)

Message 8 of 8
(3,660 Views)