02-23-2023 03:36 AM
What are the main differences between the CMH and QMH design patterns? Both are available as project template, but I cannot really find any documentation about the main differences, and about when to use one or the other.
I've looked on the block diagrams, and they are quite similar. But there are some differences as well, which I don't really understand.
Regards,
Tamas
02-23-2023 03:47 AM - edited 02-23-2023 03:48 AM
@tcsabina wrote:
What are the main differences between the CMH and QMH design patterns? Both are available as project template, but I cannot really find any documentation about the main differences, and about when to use one or the other.
I've looked on the block diagrams, and they are quite similar. But there are some differences as well, which I don't really understand.
Regards,
Tamas
As you may have guessed the two are different flavors of the same thing, used in the same way, for the same things. Some say that it is more in keeping with the dataflow paradigm because you have actual wires connecting things instead of data disappearing into one VI (enqueue) and coming out another (dequeue).
I've not seen wide adoption of channel wire technology, probably because it is relatively new, has a fair learning curve, and (IMO) has some quirks that can get you into trouble if you're not careful. On the other hand, once you get the hang of it, it really does make more sense than queues.
I haven't really adopted it because queues have always worked for me, and aren't bothered by them enough to seek a new way to do an old thing.
02-23-2023 04:04 AM
Thank you Bill for your reply.
I am slightly enlightened, and slightly confused as well ;).
As far as I can see, the CMH and QMH both using the enqueue/dequeue VIs to 'communicate' between the two handler loops. But you say that these are 'wire based' instead of queues.
Do I misunderstand you?
Tamas
02-23-2023 07:01 AM
I have been using Channel Wires since before they were introduced "publicly" in LabVIEW 2016. I gave a talk at NI Week a few years ago, where I said that they were a "better metaphor" for Asynchronous Communication than were Queues, and they had a few features that "improved" on the use of the original "Synchronization" functions (for example, the Stream is, I believe, much superior to the Queue for a Producer/Consumer design as it includes a "reasonable" Producer-to-Consumer method of dismissing the communication channel).
Regarding the Example Code that comes bundled with LabVIEW, I (personally) find the QMH and CMH examples confusing and "overly busy". Within the last month or two, I've posted (I think) "simplified" versions of the CMH in this Forum that "does one thing", namely implements a CMH model of a State Machine. I should be able to find it, but it may take me a few days ...
Bob Schor
02-23-2023 07:23 AM - edited 02-23-2023 07:23 AM
Hi Bob,
Thanks for your reply as well!
In the meanwhile I was looking into the samples. And I started to understand the CMH example. For me it is simply a producer/consumer design, where the control data transfer is based on a queue. And on the top of this there is this green channel wire that is only being used by the Message Handling Loop to inform the Event Handler Loop to terminate. If you use the Exit button, it is not even needed as the "Exit: Value Change" event will terminate the Event Handling Loop anyhow.
So I try to ignore this channel wire when I try to understand it example.
With the QMH example I still struggle a bit. I just don't get that User Event Stop vi and its wires.
I also discovered that the Core2 course has an exercise about Design Patterns (Exercise 2), and one of the examples there is a simple Producer/Consumer setup, without any fancy channel or event wires between the Producer and Consumer loop:
Maybe I just stick with this, instead of CMH or QMH...
02-23-2023 03:05 PM
@tcsabina wrote:
This is a very strange example! Did you notice that the Communication between the Event Loop and the "Message Handler Loop" is a Messenger Channel Wire? [You can tell it is a Channel Wire because it "looks like a Pipe", and can distinguish it as a "Messenger CW" as opposed to a "Stream CW" because it can branch]. It even shows the Channel Writer, but for some unknown reason, the Channel Reader is "hidden" inside a function called "Dequeue Message.vi"! But there is no Queue, and hence no need to "dequeue".
If this was supposed to be an example of a Producer/Consumer Design Pattern, the wrong kind of Channel Wire was used (IMHO). Producer/Consumer (in its purest form) relies on one Producer talking to one Consumer over a channel that does not branch. That's the Stream Channel, which has several very nice "designed-in extras" that facilitate the proper shut-down of the Stream through the use of the "last element?" and "Element Valid" terminals on the Reader and Writer.
Bob Schor
02-24-2023 03:23 AM - edited 02-24-2023 03:25 AM
No, I didn't notice that. Thanks for pointing out! It is indeed an example for the Producer/Consumer concept:
So the CMH is using a Channel to communicate between the 2 handler loops.
The QMH is using a Queue for this.
And the example in Core2 is also using a Channel. Correct?
Tamas
Edit:
There is a new version of Core2, but it seems that this particular example still using channels: