01-13-2010 06:26 PM
Hi,
I'm trying to figure out the best way to implement a producer/consumer architecture. I'm hoping there is something simple that I don't understand.
I have a state machine executing in it's while loop, doing things like saving and processing data. The data is being passed through a queue from a separate while loop. I'm currently starting that producer loop using occurrences, and I can stop it with a local variable.
What I can't figure out is how to restart that loop from within the state machine? In essence, I'd like to have a switch that says "Collect Data" and it will turn the producer while loop on and off but leave the main program running in the meantime.
Thanks for any suggestions.
mike
01-13-2010 06:40 PM
01-14-2010 03:49 AM
Mike,
the consumer should not stop the producer if no data is needed in the state machine of the consumer. Instead, just discard all data. It's just that simple. No need for information flow from the consumer to the producer at all here.
Ok, if you want to stop acquisition in the producer due to performance issues, you should use custom user events if the producer is event driven. If the producer works with a polling architecture, you have to control the producer using a global transfermechanism. Suggested way is imho a functional global (FGV) for this purpose.
hope this helps,
Norbert
01-14-2010 04:39 AM
If you are using queues you can get the the consumer loop to execute when data is available using the 'dequeue element' vi so there should be no need to use occurences. You can include a start sequence and stop sequence state to control the squence in the state machine (consumer loop) and have a seperate 'stop loop' state to stop the loop when you want to exit.
Dont forget to pass the required state and any data to the queue
01-14-2010 10:51 AM
Thanks very much for the good suggestions. There's one thing that I didn't make clear: The producer loop can't start acquiring data until the DAQ is configured, and I do that in the main state machine (i.e., the consumer loop). The reason that I've wanted to be able to stop and start the producer loop is to change DAQ parameters, such as the sampling interval. This requires re-initializing the DAQ and passing that to the producer loop.
Not sure if what I want to do is the right way to do things, of course.
If I'm reading Ravens Fan correctly, I could basically have a separate state machine for the producer loop with the state driven by local variables from the consumer loop. That would certainly accomplish my goals. Is there any reason that's not a good way to do things?
One point is that performance isn't an issue; I'm sampling at 10 hz and saving data a 1 hz.
Thanks again!
mike
01-14-2010 11:01 AM
Without getting too deep into it, you can have the produce loop's DAQ configured from the consumer loop, if you encapsulate the DAQ in an action engine. What this is basically is a functional global that contains the various DAQ functions such as configure, acquire, close, and you can then place it both the consumer and producer loops. What it does is store the information, such as board refnum, in the functional global, so that there doesn't have to be the wired reference passed from one DAQ function to the next.
Just a thought, a long, stressful night/morning so far, taking a break to lead others astray here!
01-14-2010 11:16 AM
mooseo wrote:
If I'm reading Ravens Fan correctly, I could basically have a separate state machine for the producer loop with the state driven by local variables from the consumer loop. That would certainly accomplish my goals. Is there any reason that's not a good way to do things?
Yes, that is pretty much what I'm thinking.
Though, Putnam's idea is an excellent one. I'm a big fan of action engines. Unless I'm doing something really basic, I try to encapsulate any related functions in an action engine.
01-14-2010 12:12 PM - edited 01-14-2010 12:13 PM
Basically, i find producer/consumer architectures where the consumer creates "commands" (Edit: which do more than simple notification tasks) for the producer quite absurd.
I would switch to a three loop architecture:
Producer A is responsible for UI display/control. It feeds Consumer A which is infact Producer B.
Producer B (aka Consumer A) is the DAQ consumer. It will acquire data due to the settings passed by Producer A. The DAQ data will be passed to Consumer B.
Consumer B handles the data passed by Producer B. If necessary, it can create custom user events in order to notify Producer A about certain situations in the software.
An approach with an Action Engine can be similar in regard to functionality, has its own advantages and disadantages.
hope this helps,
Norbert
01-15-2010 06:25 PM
Thanks very much for all the help. I've spent a lot of time reading about action engines and it's been very informative.
cheers,
mike