The QMH is well-documented on the NI website. Here is a good overview for a situation where the producer event handler manages user interface interactions: https://decibel.ni.com/content/docs/DOC-14169. In the example there, the queue data type is an enum indicating the message to handle. Here’s a code snippet.
Figure 1 – QSM Example
In this example, pressing the Start button on the UI causes the ‘Initialize’ state to enter the queue whereupon it is received by the consumer loop. The ‘Initialize’ frame of the consumer loop cases pushes a ‘Process’ state onto the queue. The ‘Process’ state causes a random number to be summed iteratively (into a while loop shift register), while the ‘Process’ state is pushed onto the queue until the total exceeds 25. At that point, the ‘Report’ state is pushed onto the queue and the VI reports the result. Since nothing else is pushed on the queue, the consumer loop awaits further instruction, which must come from the producer loop.
An obvious benefit of this architecture is the responsiveness of the UI while the app is busy performing some task. Some earlier implementations of a QSM were done with a single loop (i.e., producer and consumer in one loop), but this implementation may become unresponsive to the user.
Better Queue Element
All you readers should know by now that it is better to create a queue data type that holds both the message and the data upon which to act or to describe the message payload more precisely. The element holding the data is often a Variant, allowing (almost) any type of data to be passed in the queue.
Non-Local Queue and Event Usage
There is no reason that queue usage needs to be confined to this producer and consumer loop. Since a queue can be named, access to a queue can happen anywhere in any VI. Thus, other parallel loops can communicate with this consumer loop by pushing messages on the queue. For example, a background data acquisition or safety monitoring loop can push sampled data or alarm info onto this queue for handling at this “main” application level.
Likewise, user events can be created to cause the consumer loop to response to events other than the press of a button on a UI. An alarm handler might be best suited for monitoring an event created when the application detects a problem. For example, an alarm event would cause the producer event case to analyze the alarm, determine the best course of action, and push the appropriate messages onto the queue for handling in the consumer loop.
Changing Thought Patterns?
It is interesting to see how far the adoption of good programming practices has come in the last several years. Take a look at the discussion in this forum: http://forums.ni.com/t5/LabVIEW/please-don-t-do-it/m-p/381751?view=by_date_ascending. Note how some developers think the use of a QSM is overkill for situations where sequential flow (i.e., stacked sequence frames) is sufficient. Granted that they may be an acceptable statement for a simple app, but an app hardly ever stays simple.