LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Problem: Accessing "Singleton" object from multiple VIs

 Hi,

 

I'm having a problem. My final goal is to have something like a singleton pattern, except that it should hold an object for each COM-port. I wanted this to also work spanning multiple VIs, i.e. I have a GetInstance-VI that I call with the port-name and if an object for this port already exists, I get a reference to this object, otherwise, a new object is created. To do this, I use a reference class (a Class that has a 1-Element-Queue with the Private Data and a 1-Element-Queue with the Lock State). This all works very well, i.e. if VI1 calls GetInstance with COM1, a new object is created, if VI2 after it calls GetInstance also with COM1, it gets the same object (actually a copy but the queues still point to the same data). Now both can work on this object independantly.

 

However, the problem is, that apparently this object gets destroyed once VI1 is stopped (i.e. the queues become invalid), even though VI2 still using them, so an error occurs.

 

I wonder what would be a good solution for this? Is this even possible?

 

I attached a small project that doesn't use any data but just a "Lock State" queue to show what's the problem.

 

To see the problem, open gettest1.vi and run it, then open gettest2.vi and run it and put a probe on the object inside the loop. You will see that both operate on the same queues. Now when you stop gettest1.vi, an error will occur and you will see that the queue in the probe from gettest2.vi says something like "invalid refnum".

 

If you have any hints on how to do this right, I'd be extremely happy. 🙂

 

Thanks,

 

Tobias

0 Kudos
Message 1 of 5
(3,133 Views)

Your problem is that LabVIEW automatically clears references when the hierarchy they were first created in goes idle or out of memory. Since this only actually applies to references, you can work around this by opening another references to the queue from the second hierarchy.

 

I didn't look at your code, so this description might need some changing, but essentially, you should get the call chain in the Get Instance VI and check the name of the top level VI. If it already has a reference in the cache, you use that. If it doesn't, you open a new reference and associate it with the VI's name. You will probably also want to check the queue (e.g. by getting its status) and if there's an error close the existing ref and open a new one.

 

Alternatively, you can launch a daemon VI to create the queue and have it stay in memory until the program is over. You just need to make sure that it obtains the queue first.


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

Hi,

 

thanks for the reply. However, I'm not quite sure how to do this here, since the queues are part of an object. So both VIs have a copy of the object and both should have the same references to queues contained. However those get invalid. So, the only possibility would be to clone the object and while doing this obtain new references to the same queues and put them in the cloned object. How can one do this (create a new reference to an unnamed queue).

 

I will be away for a week starting in a couple of minutes so I will come back to this thread after this.

 

Thanks,

 

Tobias

0 Kudos
Message 3 of 5
(3,123 Views)

I thought about this again and I think even this will not do since there are queues deeper down in the object as well, so I guess those references will become invalid, too.

 

Isn't it possible that an object (with all the data it contains, queues included) exists independant from the VI that first created it? In Java the solution to this is Garbage Collection... A reference should never become invalid if there is still an object holding that reference... 

 

I guess what I *could* do is to have a server VI running permanently in the background to hold the references but this is not really nice. 

0 Kudos
Message 4 of 5
(3,115 Views)
LabVIEW does have garbage collection (since before Java even existed 😉 ) and the rule for when to automatically destroy a reference is as I stated before. As you understood, the way to create a reference which will not go out of memory is to have a daemon for managing the references.

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