06-23-2016 02:26 PM
Has anyone come up with way to instantiate a new queue/notifier/event/DVR reference that is guaranteed to avoid garbage collection, such as is done automatically when a dynamically-launched VI stops executing?
Background:
I have been bitten before where I have a couple of asychronously-launched VI daemons that need to register for/generate some commonly-shared event. I have a simple action engine that creates the Event reference on first call and stores it in a feedback node, providing functional-global variable (FGV) behavior; each daemon can just plop down this FGV to have access to the reference.*
The problem, then, is that the first daemon to call that action engine/FGV will "own" the reference, and if that daemon instance is killed, then the reference dies with it, even if other daemons are still running. I would like to find a way to prevent that garbage collection--to keep the reference alive even if its "owner" stops running.
Sure, the simple solution is to drop the FGV on the top-level diagram. But let's assume I can't (or don't want to) do that any time I add one of these FGVs. Is there a way I can effectively tell LabVIEW: don't ever destroy this reference automatically? Has anyone encountered this problem and found a good solution?
*(typically there's a little more to it than this. The FGV may be privately scoped in a library, and the public methods of the library will hide this from callers. But this example shows the gist of the problem.)
06-23-2016 02:32 PM
Something tells me "let the AE open a refrence to itself."
You of course will tell it that does not work.
Ben
06-23-2016 04:29 PM
@TurboPhil wrote:Is there a way I can effectively tell LabVIEW: don't ever destroy this reference automatically?
No. I have heard from people at NI about consideration for changing this so that the reference is only released when all of its callers are done, but nothing has been done about it so far.
The obvious practical answer is the one you already have. Another is not to use tools like that, but to have something explicitly create and pass the reference in the caller, but that would require a change in how the code works which I'm sure you don't want.
Note that this behavior affects references, not resource. If you have a resource which can have multiple references (like a named queue) then each reference will be destroyed when its owner goes, but the queue will only be destroyed if all references to it are destroyed. This won't help in your event example, and generating additional references in the FGV based on the call chain is possible, but not all that elegant.
06-24-2016 06:26 AM
@TurboPhil wrote:Sure, the simple solution is to drop the FGV on the top-level diagram. But let's assume I can't (or don't want to) do that any time I add one of these FGVs. Is there a way I can effectively tell LabVIEW: don't ever destroy this reference automatically? Has anyone encountered this problem and found a good solution?
*(typically there's a little more to it than this. The FGV may be privately scoped in a library, and the public methods of the library will hide this from callers. But this example shows the gist of the problem.)
Have the AE, on first call, launch its own "system daemon" which creates and owns all the references and then stays running till you tell it to stop. The existance of this can be hiden from Callers. Have the system daemon shut down if all the references have been closed.
06-24-2016 09:42 AM
@drjdpowell wrote:
Have the AE, on first call, launch its own "system daemon" which creates and owns all the references and then stays running till you tell it to stop. The existance of this can be hiden from Callers. Have the system daemon shut down if all the references have been closed.
Hmm. Good call. Do you happen to know if there are gotchas with dynamically launching VIs from other dynamically-launched VIs? Anything that might affect lifetime of the VIs themselves or the references they spawn?
For instance, I would *guess* that if I launched A.vi with a "Run" method, and then A.vi did another "Run" method for B.vi, then I would need to make sure to set "Auto Dispose Ref" to be TRUE so that ownership is transferred to the dynamically-launched VI, correct?
https://zone.ni.com/reference/en-XX/help/371361H-01/lvprop/vi_run_vi/
What about for asynchronous call-by-reference nodes?
06-25-2016 02:13 PM
@TurboPhil wrote:Do you happen to know if there are gotchas with dynamically launching VIs from other dynamically-launched VIs? Anything that might affect lifetime of the VIs themselves or the references they spawn?
I don't believe there are any "gotchas", and I use dynamically launched VIs extensively.
06-26-2016 12:45 AM
@TurboPhil wrote:
What about for asynchronous call-by-reference nodes?
I was told by someone in R&D once that regular CBR calls are not considered top level VIs and that he wasn't sure about ACBRs. I never tested it myself directly, but I know of things which rely on it, as JDP points out (and I believe if you look at the call chain, you will see they are launched by a "special" VI).
06-26-2016 08:57 AM
This is a very interesting discussion. I hope you don't mind me leaning in and taking notes? 🙂
06-26-2016 12:35 PM
About four years ago, I worked on a Project that spawned at least 48 Start Asynchronous Call detached routines (there were 24 "Camera Clones", same re-entrant VI running 24 video cameras and 24 Balance Clones running Mettler balances). We had code (in the form of a VIG) to get them all to stop when told to do so, but (especially the Balance Clones) they would sometimes "get stuck" and become unresponsive, staying running even after everything else had stopped.
Short of logging off or rebooting, we wanted a way to (a) find any running top-level VIs, and (b) abort them. I wrote a small utility that basically does an App Property to get the name of All VIs in Memory, uses the names to get a VI Reference, checks the Exec State, and if Run Top Level, closes the Front Panel and Aborts the VI. Of course, I need to make sure I exclude this VI itself (we don't want it committing suicide). So, Yes, Asynchronous VIs can persist after everything else has finished, and you can detect and "do something" about them.
Bob Schor
05-23-2017 02:16 AM
If you simply open/create the queue ref by name, anyone using that named queue should keep it alive, no?
/Y