LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

producer consumer vs state machine


DFGray wrote:

To keep things simple and scalable for future expansion, I like to have single point sources for my data and user interaction, and single sinks for data handling.  In your case, this would mean one loop for events and one for datasocket monitoring. 

 

Exactly, that's what I am trying to do.

 

Data handling should be done with a third loop.  If UI events need special handling, they can be a fourth loop or handled in a case structure in the main UI loop (asynchronous or synchronous - your choice).  This is a common architecture that is easily expandable (for a full blown example, see this post).  One key to making it work is separating action handling from events.  This allows you to essentially intermingle a state machine into a producer consumer architecture.

 

Yes. I have tried to do so in the posted designs.

 

Short answer, you want both a state machine and a producer consumer architecture.  See the example above (all the posts) for an example.  It does essentially what you want to do, but using input from a sound card instead of datasockets.

 

Yes, you've posted a well documented example. I opened the XylophoneTunerXIII, but then I saw Core Architecture thread, and I guess that's what you wanted me to see in particular, yes?

 

If yes, I see there is UI event handling. But I don't see the data event handling (from sound card, as I want to do from datasocket). Can you tell me please the file where I should look? Or may be I am missing to understand something. 


 

Message Edited by Vaibhav on 08-29-2009 08:21 AM
Vaibhav
0 Kudos
Message 11 of 33
(2,426 Views)

Sound card data acquisition is being handled in a subVI - ASQ.lvlib:AcquireSound.lvclass:ExecutionLoop.vi (on disk, this is simply ExecutionLoop.vi).  It is the first subVI in the bottom fork of the error wire during the initialization.  It implements a task handler, to handle GUI events, and a simple two-state state machine (running, not running).  It also feeds the pulse analysis loop on the main diagram through the use of a queue.  This loop contains:

  1.  Producer - it produces the sound waveform for pulse analysis.  This could be replaced with your datasocket code (with appropriate changes to the initialization, configuration, and cleanup code).
  2. Consumer - it reacts to UI events to start and end the data collection
  3. State Machine - it has different actions depending on the whether it is running or not running.  The case statements in the loop which implement the state machine could easily be expanded using an enum as the input instead of a boolean to handle more states.
The pulse analysis loop would have been placed in a subVI, as well, but it interacts with the GUI, so was left on the top level diagram for performance reasons.  Let me know if you have further questions.
Message 12 of 33
(2,415 Views)

Hi Dr Damien,

 

I studied the file. the coding is very good. You have tried to accomodate everything in one single loop, which is good, but I would say this is what I am explaining, that I cannot have everything in one single loop (technically I can have, but I don't want) because I want the User Events and Events based on the Datasocket data to be executed in parallel.

If I talk about my application from your template, then, if the user clicks some button on the front panel, several actions can occur, like sending somed data to datasocket, calculations, change of attributes and so on... and this would take some time... Meanwhile, if there is already some data on datasocket, then it would be processed (or the event related to that data would be processed) ONLY after this user event has finished. Yes?

 

Thanks ahead!

Vaibhav
0 Kudos
Message 13 of 33
(2,396 Views)
Any replies guys?
Vaibhav
0 Kudos
Message 14 of 33
(2,376 Views)

Actually, no.  Your datasocket handling loop should be separate from your UI handling loop and should run independently from it (short of responding to commands, when needed).  The Xylophone Tuner has such a three-loop structure.  The top loop in the main VI is the UI handling loop.  It is a synchronous UI handler which contains both the event structure and the event command cases.  Some people prefer to separate the event structure and event handling into two loops (see discussion on architecture post of Xylophone Tuner).  The bottom loop in the main VI is the data processing loop.  In the Xylophone Tuner, this searches the sound data for events and posts the analysis to the GUI if found.  In your case, this would be a loop to do whatever processing is necessary for the datasocket data.  Finally, there is the data collection loop.  In the Xylophone Tuner, this is in the VI discussed earlier.  In your case, this would be the datasocket acquisition loop.

 

In a properly designed application, UI events should not prevent data processing from happening.

Message 15 of 33
(2,362 Views)

Yes, sounds like what I'm trying to build.

 

But in the previous message, I couldn't find out which is your Main VI? I thought of Initialize.vi, but it has no subvi calling in the bottom fork of the error node (as you wrote earlier) calling the ASQ.lvlib:AcquireSound.lvclass:ExecutionLoop.vi.

 Or is it XylophoneTuner.vi ?

In the XylophoneTuner.vi I found this case in the "Initialize" state (which sounds like ur sentence "It is the first subVI in the bottom fork of the error wire during the initialization") But still not sure if you're talking about the one in the "Run" node in the image below (from ur code, I hope you didn't mind).

Is it possible to have some brief documentation of this, which explains about the nodes etc?

 

 CallingExecutionLoop.png

 

In a properly designed application, UI events should not prevent data processing from happening.

How true!

Thanks for your support!

 

Message Edited by Vaibhav on 09-04-2009 03:42 PM
Vaibhav
0 Kudos
Message 16 of 33
(2,330 Views)

The main VI is Xyl.lvlib:XylophoneTuner.vi.  Make sure you get the latest code from the last post (the one about documentation).  Earlier code will not have the data acquisition loop, since it was not implemented yet.  You may want to walk through the development process so you see how the application was created and why.  Most of the reasoning applies to your application, as well.  This will also present the various parts of the program one at a time instead of all at once, as in the final code.  The location in the main VI is as follows:

 

DataAcquisitionLoopLocation.png

Message 17 of 33
(2,288 Views)

Thanks Dr Damien,

 

Appreciated your informative answer. The latest version I have is XIII. Please give me link to the latest if this is not the latest.

 

Yes, I DO like to see the entire process and not just the end product, as I myself believe in a well designed product with proper documentation. But I am at the very high point of the implementation of my application. Still need to write (or rather Draw) a lot of stuff in my application. And you know that vhooshing sound of the deadlines, as they fly by, well, I am just listening to it everyday. So right now I won't study everything, but with my selfishness powered by my curiousity, I just want to know how have u implemented the Events capture and execution loops, Data aquisition loop, and data events loop, to see how it fits with mine.

 

I have half developed one of the modules (other 2 will follow the same path) and I am using a big state machine loop, which, in more than one states, has event structures (I can see those raising eyebrows, and hear those Dooohhhhhs!!!) and I would have to implement the Datasocket reading (and corresponding actions) loop in more than one states too.

I have a previously developed, and well working, application developed by one of my professors, who also agrees that it was developed a long time ago but would like to put it with state machines.

If not anything else, I would just use that model (running several loops in parallel) into my state machine's state.

 

But would like to understand your method.

 

also, from the discussion so far, I can understand you have these loops in different VIs. Right? So are they running in parallel? I mean, if you call a subVI, it would need to finish the execution before the control returns back to the calling VI, no? 

Vaibhav
0 Kudos
Message 18 of 33
(2,269 Views)

Will it be too much if I ask you to make a template which shows the program flow clearly?

I know I am being demanding, but it would explain me easily how you are talking about the loops to interact. Because, alongwith the above queries, I need to understand many other nodes in your program, and a simple block diagram with just loops etc. would explain me exactly what you're talking about.

 

Thanks ahead!

Vaibhav
0 Kudos
Message 19 of 33
(2,258 Views)

LabVIEW has a concept of "clumps".  Each clump can be executed in an independent thread once its inputs are valid.  Loops are typically clump boundaries, so each loop on a block diagram can operate in an independent thread.  The Xylophone Tuner has three loops (one of which is in a subVI).  These are for UI event handling, data acquisition, and data analysis.  Data and commands are passed between the loops using queues.  States are implemented as case statements in all loops (e.g. in the Run state, a configuration command on the data acquisition loop stops the data acquisition, reconfigures, and restarts it.  In the idle state, nothing happens, since configuration is done at startup).  Different states can result in different behavior in all the loops.

 

So, if control is passed to a subVI in one loop, the other loops continue processing normally (assuming your processor has sufficient threads to do this).  The exception to this is if a subVI is used in two loops and the subVI is not reentrant.  In this case, the subVI in one loop would block its use in the other loop.  The subVI should probably be reentrant for this use case so both loops can freely and independently execute.

 

I would strong recommend you eliminate all but one of your event structures and implement states in the single event structure with one case statement per event.  While there are advanced use cases which are more easily handled with multiple event structures (and, hopefully, dynamic event registration), your use case is not one of them.

 

Unfortunately, I do not have the time to write the example you wish.  I, too, have deadlines...

Message 20 of 33
(2,242 Views)