LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Access to Class data in multi-threaded application with OO in 8.2

I am intrigued with the new object oriented capabilities in LV 8.2.  I have been a long-time GOOP user.  My question is how does LV handle access to a classes data in a multi-threaded (execution system) application.  For example if I have two while loops that can possible access a classes member variable does the access get controlled behind the scenes?  If so how?  In GOOP there was a get data and get data to modify VI which would "lock" access to the member variables.  I do not see this in LVOO.
 
John
0 Kudos
Message 1 of 10
(4,370 Views)
GOOP and LVOOP are two different takes on object-oriented programming in LabVIEW, and both have their separate advantages. GOOP is a toolkit that uses a by-reference model for accessing class data. This necessitates having locks for data that can be accessed from multiple threads.

LVOOP is much more akin to LabVIEW's native dataflow style. It is a by-value implementation. If you fork your wire with your class data, there is a chance LabVIEW will make a copy of your class. So accessing LabVIEW class data in two separate threads is identical to accessing any other two LabVIEW values in separate threads. There has been much discussion on which is better, by-value or by-reference. LVOOP is probably the first by-value OOP methodology invented, and many accustomed with OOP had to get used to that. But it does have the benefit of fitting in perfectly with LabVIEW's dataflow programming style.

That being said, you can implement custom by-reference models using the by-value syntax of LVOOP. One popular way is to make your class data a single-element Queue reference to an inner class. You can pass around the Queue reference, but if you branch wires, you're only copying the reference to the inner class, not the inner class itself. Accessing the inner class data is very similar then to the Get Data and Get Data to Modify functions in GOOP. If you preview your inner class data in the queue, you are just getting data. If you dequeue it, you are locking the data by removing it from the queue. All other requests to the queue in separate loops will have to wait for you to check the data back in by re-enqueuing it. There is nothing special about LVOOP in this case when it comes to protecting shared data.

Check the Example Finder for an example that uses this by-reference/by-value implemenation. I believe it's called the Singleton example.
Jarrod S.
National Instruments
0 Kudos
Message 2 of 10
(4,363 Views)

By the way, this is a fantastic in-depth article explaining the reasoning behind LVOOP.

 
Jarrod S.
National Instruments
0 Kudos
Message 3 of 10
(4,363 Views)

Jarrod,

 

Thanks - I will checkout the link.  I guess I'll have to think of the direction to go.  Seems like a little bit of "cludge" to do the queue method and I would always have to branch the queue reference and not the class since that would be copied in the new execution system.  I like to use the concept of the event structure to capture UI events that update a class that is essentially doing it's processing in another execution system.  Maybe I will have to prototype and check performance.

 

John

0 Kudos
Message 4 of 10
(4,358 Views)
I find it ironic that the "cludge" you dislike is the actual implementation used by at least one of the GOOP toolkits (dqGOOP) and is the basic principle behind all of them. 😉
0 Kudos
Message 5 of 10
(4,309 Views)
Aristos -
 
Do you have more detailed documentation on the architecture of GOOP?
 
John
0 Kudos
Message 6 of 10
(4,288 Views)
Not really. All of the toolkits (GOOP Toolkit, dqGOOP, OpenGoop) are 3rd party tools (not NI). You'll have to ask those developers their secrets.
0 Kudos
Message 7 of 10
(4,284 Views)
From your comment it would seem that the "reference" I pass with GOOP is not the object but a queue reference (my cludge comment). I was wondering how you made that determination? Most of the vi's from Endevo are password protected.

John
0 Kudos
Message 8 of 10
(4,266 Views)

Working at Endevo I can give some input as regards our GOOP architecture, GOOP 2, used by our toolkit: GOOP Inheritance Toolkit (GOOP Wizard 3).

 

Our Wizard generates a class object repository using an un-initialized shift register to store object data. We also use another shared repository which is also an un-initialized shift register.

 

The GOOP reference is basically a pointer to find the correct element index in the array holding all object data of a class. Then, of course, since we support inheritance it is a bit more complicated. What appears to be one object is actually composed of data stored in one un-initialized shift register per class in the inheritance hierarchy.

 

As regards locking we use Occurence to lock the object while data is modified.

 

The architecture works well in a parallell execution environment. The objects created will exist in the memory context (application instance) they are created in and cannot be accessed in another memory context. This is standard LabVIEW behaviour and has nothing to do with GOOP.

 

If you need more info I am happy to assist. The VIs are locked mostly to protect the way we implemented inheritance and virtual methods and also to simplify maintenance. We maintain the class templates and the Wizard have a feature for upgrading existing classes to new versions of the class templates used.

 

Thanks,

Jan Klasson

www.endevo.se

0 Kudos
Message 9 of 10
(4,254 Views)
The queue version of this is used by dqGOOP (pronounced "Dequeue GOOP", so you can hear the relationship).
http://dataact.com/dqGOOP.htm
0 Kudos
Message 10 of 10
(4,242 Views)