From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Reentrant functional global variable (RFGV) is interupted by front panel controls

Solved!
Go to solution

Hello

I though Í had found the ultimate way to manage memory in a dynamically changing system. I read about the RFGV here: http://labviewwiki.org/Functional_global_variable and put together a normal static FGV to keep track of the references for each created instance of memory which I then easily could call back just by a name. But now I found that all RFGV stops completely whenever a front panel control with a menu is used, i.e. "enum", "ring" or "path control". I've tried putting them in different execution systems but no luck. I read about this guy that might have stumbled into the same problem: http://forums.ni.com/t5/LabVIEW/Do-I-need-to-use-a-semaphore-when-reading-writing-a-functional/m-p/1... but he got no help what I could see.

 

I've not tried semaphores. Not sure what that is all about. Check my little test code and tell me what I'm doing wrong. Or maybe there is no solution in which case I have to abandon the idea of using RFGV's for anything at all. Maybe all VI's holding memory have to be statically assigned.

 

Run the code (in LV2009) and watch the 6 LEDs blinking. Then click on anyone of "enum", "ring" or "path" (the file dialog) and watch the LED's stopping where dynamic memory is used for writing or reading while the static VI continoues.

 

Any suggestions?

best regards

Kai

0 Kudos
Message 1 of 9
(5,365 Views)
Solution
Accepted by topic author user_4342726352435

If memory serves, what you're running up against is not the UI thread, but an internal LV mechanism called the root loop, which some things have to run in. Specifically, in your case, the Run VI method and showing a menu (either an actual menu, or a pop-up menu from a ring).

 

You can work around this (and simplify your code considerably) if you use the Call by Reference node instead of the Run VI method, but I wouldn't recommend this anyway, since I'm guessing your code does not do what you think it does. Handling memory in LV can be quite complex if you want to be able to control it, so if you really feel you need it, I suggest you start by looking up some existing materials on memory management in LV.

 

 


___________________
Try to take over the world!
0 Kudos
Message 2 of 9
(5,339 Views)

Thank you very much Tst for the tip. It now works like a clock. I saw the recommendation of using the "call by reference" at

 

http://labviewwiki.org/Functional_global_variable

but all examples I found was using the "run vi" method:

http://forums.ni.com/t5/LabVIEW/How-do-I-use-a-static-reference-to-keep-a-VI-in-memory-but-then/m-p/...http://labviewwiki.org/Functional_global_variable

  http://digital.ni.com/public.nsf/allkb/9CE784F50F816EA18625751900775EBB

 

There are not much information about this to be found on the Internet. But right now I found something about reentrant VI's in chapter 7 of the "LV advanced I course" but not the specific combination of "call by ref" and reentrant "FGV". The examples here are also using the "run vi" method. But I'm not sure why you NOT recommend me to use this (right now it's working fine) or why you say that "your code does not do what you think it is". I'm definitely NOT interesting in just poking around in the memory just to "control it" for no good reason. I try to find the best way to build a kind of module for each of my instrument type. Each "module" should be easily connected to a subpanel of a super VI where I sometimes handle up to 8 different instruments. I would like to just increase an array when I have to add another instrument of the same type. Then connect it to it's own loop on the block diagram and as easy as possible connect the transfer of data between the sub-vi module and the super-vi. The super-vi should be able to further treat the data and display it in new ways and maybe handle schedules and relays and save combination files for the whole system. For this problem so far the missing link has been different kind of dynamic memories holding the state of each instrument and all produced data. I have always been forced to continue evolving the memory part when there comes a new system with even more instruments of the same type. Naming the static memory xx1,2,3,4 and so on and then go through the complete system where they are called and change names. It's tedious work. Not to mention all the different versions of all systems (I think it might be more than 10 different systems now and still evolving). Using RFGV is not what I would think of as too complicated considering what the gain is. But still I would not like to run into some other (yet unknown) problem in the future.

 

I'm very open for suggestions if you think you have a better solution. I really appriciate your help.

 

best regards

Kai

 

0 Kudos
Message 3 of 9
(5,317 Views)

Now I understand. I thought your intent was to manage the way LV allocates memory, which is why I said the code probably does not do what you think it does.

 

You are correct that creating a piece of code once and then being able to access N "copies" of it at run-time can be very useful. This is one of the basic concepts behind object oriented programming, which I suggest you read up on. For a long time, LV didn't have any OO capabilities, but that did not prevent people from emulating that part of them. This type of code was generally known as GOOP, and one of the variants (OpenGOOP) even used RFGVs at its core, just like you do.

 

You can see one such example (with details) here, although I would recommend reading the entire thread. In these frameworks, the copies (or objects) are identified by a reference, not by a name, as you'll see in the example.

 

It's important to note that LV does have OOP today, but the built-in version is by-val, unlike the by-ref version which you probably want. There are solutions for this and as you read up on the topic you will presumably run into them.


___________________
Try to take over the world!
Message 4 of 9
(5,293 Views)

I ran into the very same issue a few weeks ago... Functional reentrant global.  My resolution was to use a queue (thanks Greg), so as to avoid the run method.  In my case, I was using it for the status of a 'slot' in a test system (where I have 10 (slots) of the same thing).  I use a lossy enqueue to push the data in that I care about, and that pops off the old data.  and instead of dequeuing (because I read the status in several places in any one of 15 parallel loops) I use a preview queue element.  Works very well and I no longer have the conflict in the UI thread where the system hangs when an OS prompt is opened..  


Paul
0 Kudos
Message 5 of 9
(5,282 Views)

Thanks tst and PJS for your suggestions. I have to continue to LV OOP and read all about that. (I actually had that on my "to do list" already but there never seems to be time enough, always hunted by new (and old) projects that must be ready NOW...)

But before I'm there I wonder if you recommend to use the "call by ref" or "run-vi" methods when loading a sub-vi, holding all communication with a specific instrument type, to a sub-panel. For the RFGV's the "call-by-ref" seems natural since they are meant to open and exit in a jiffy. But the instrument sub-vi is supposed to run until the main vi is closed. With the "run-vi" method I can select FALSE for "wait until done" and still put in and out data with that reference until I close the application. I also noted that the instrument -vi's are NOT hanging due to menu use (as the RFGV's were) even though they are started with the "run-vi" method, maybe because the only use of the reference is the "final close" command to the sub-vi. I know there are many ways to communicate between the super and the sub-vi, e.g. globals, (R)FGV's or queues. For the basic data transfer I have always used the queue just as "PJS" suggested. But I don't know if the queue will work if the instrument-vi is started with the call-by-ref which does not finish until the VI finishes.

So, considering the thread "stability" AND the continoues communication between the sub-vi and the super-vi, which method is better?... or is it just about taste?

best regards

Kai

0 Kudos
Message 6 of 9
(5,219 Views)

First, you should note that the VIs in your original example weren't hanging either. Rather, the Run VI method was waiting for the menu to disappear before it could execute.

 

Second, the main functional difference between the CBRN and the method is that you can run the VI without waiting for it to end (at least until this idea is implemented). If you need that (and people sometimes do), use the method. If you don't, use the CBRN, as it allows you to pass inputs and outputs cleanly.

 

Third, there are many communication methods, as you pointed out. The most appropriate one depends on the exact nature of the code.


___________________
Try to take over the world!
0 Kudos
Message 7 of 9
(5,207 Views)

Very intersting links you have given me, the one about Ben's AE and your "CBRN dont wait" idea. I notice there was no comments on Ben's point in the end using "skip-if busy" with a sub-routine. I guess that would work already and I could use it together with a normal queue parameter, right? Or would the "subroutine" consume most of the priority since if I remember it correct it's above the "time-critical" level ?

(No it's not "hanging" it's just busy "waiting"..haha that was funny.. in my vocabulary it's the same. But maybe for a pro "hanging" is something which NEVER returns.. and I have to use some other word... maybe it's "chilling" ? Because the word "waiting" I reserve for myself when I'm getting more and more pissed observing the phenomena...)

Kai

0 Kudos
Message 8 of 9
(5,196 Views)

I believe the skip... option is only relevant in LV real-time. I don't think it works in Windows. In any case, I never used it and I don't suggest that you do either, as setting it will cause the VI NOT to execute, not to mention the point you brought up of subroutines requiring a lot of attention from the CPU.

 

As for the terminology, my point wasn't about which word you use, but about a basic difference - nothing was stuck. The method itself was simply waiting for a single resource so that it could execute. As soon as that resource became available, the method executed and the VI started to run.


___________________
Try to take over the world!
0 Kudos
Message 9 of 9
(5,185 Views)